PageRenderTime 83ms CodeModel.GetById 40ms app.highlight 12ms RepoModel.GetById 29ms app.codeStats 0ms

/src/UnitTests/IOC/FluentExtensionTests.Implementation.cs

http://github.com/philiplaureano/LinFu
C# | 125 lines | 87 code | 22 blank | 16 comment | 0 complexity | 18de321bbe9dc6774168b16560af7ddb MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using LinFu.IoC;
  4using LinFu.IoC.Configuration;
  5using LinFu.IoC.Interfaces;
  6using Xunit;
  7using SampleLibrary;
  8
  9namespace LinFu.UnitTests.IOC
 10{
 11    public partial class FluentExtensionTests
 12    {
 13        private static void TestOncePerThread(string serviceName,
 14            Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>>
 15                doInject)
 16        {
 17            Test(serviceName, factory => factory.OncePerThread(), doInject, VerifyOncePerThread);
 18        }
 19
 20        private static void TestSingleton(string serviceName,
 21            Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>> doInject)
 22        {
 23            Test(serviceName, factory => factory.AsSingleton(),
 24                doInject, VerifySingleton);
 25        }
 26
 27        private static void TestOncePerRequest(string serviceName,
 28            Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>>
 29                doInject)
 30        {
 31            Test(serviceName, factory => factory.OncePerRequest(),
 32                doInject, VerifyOncePerRequest);
 33        }
 34
 35        private static bool VerifySingleton(string serviceName, IServiceContainer container)
 36        {
 37            // The container must be able to create the
 38            // ISampleService instance
 39            Assert.True(container.Contains(serviceName, typeof(ISampleService)));
 40
 41            // The container should return the singleton
 42            var first = container.GetService<ISampleService>(serviceName);
 43            var second = container.GetService<ISampleService>(serviceName);
 44            Assert.Same(first, second);
 45
 46            return true;
 47        }
 48
 49        private static bool VerifyOncePerThread(string serviceName, IServiceContainer container)
 50        {
 51            var results = new List<ISampleService>();
 52            Func<ISampleService> createService = () =>
 53            {
 54                var result = container.GetService<ISampleService>(serviceName);
 55                lock (results)
 56                {
 57                    results.Add(result);
 58                }
 59
 60                return null;
 61            };
 62
 63            Assert.True(container.Contains(serviceName, typeof(ISampleService)));
 64
 65            // Create the other instance from another thread
 66            var asyncResult = createService.BeginInvoke(null, null);
 67
 68            // Two instances created within the same thread must be
 69            // the same
 70            var first = container.GetService<ISampleService>(serviceName);
 71            var second = container.GetService<ISampleService>(serviceName);
 72
 73            Assert.NotNull(first);
 74            Assert.Same(first, second);
 75
 76            // Wait for the other thread to finish executing
 77            createService.EndInvoke(asyncResult);
 78            Assert.True(results.Count > 0);
 79
 80            // The service instance created in the other thread
 81            // must be unique
 82            Assert.NotNull(results[0]);
 83            Assert.NotSame(first, results[0]);
 84
 85            // NOTE: The return value will be ignored
 86            return true;
 87        }
 88
 89        private static bool VerifyOncePerRequest(string serviceName, IServiceContainer container)
 90        {
 91            // The container must be able to create an
 92            // ISampleService instance
 93            Assert.True(container.Contains(serviceName, typeof(ISampleService)), "Service not found!");
 94
 95            // Both instances must be unique
 96            var first = container.GetService<ISampleService>(serviceName);
 97            var second = container.GetService<ISampleService>(serviceName);
 98            Assert.NotSame(first, second);
 99
100            return true;
101        }
102
103        private static void Inject(string serviceName, Action<IGenerateFactory<ISampleService>> usingFactory,
104            Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>> doInject,
105            ServiceContainer container)
106        {
107            // HACK: Condense the fluent statements into a single,
108            // reusable line of code
109            usingFactory(doInject(container.Inject<ISampleService>(serviceName)));
110        }
111
112        private static void Test(string serviceName, Action<IGenerateFactory<ISampleService>> usingFactory,
113            Func<IUsingLambda<ISampleService>, IGenerateFactory<ISampleService>> doInject,
114            Func<string, IServiceContainer, bool> verifyResult)
115        {
116            var container = new ServiceContainer();
117
118            // HACK: Manually inject the required services into the container
119            container.AddDefaultServices();
120
121            Inject(serviceName, usingFactory, doInject, container);
122            verifyResult(serviceName, container);
123        }
124    }
125}