PageRenderTime 150ms CodeModel.GetById 60ms app.highlight 41ms RepoModel.GetById 44ms app.codeStats 1ms

/src/UnitTests/IOC/ResolutionTests.cs

http://github.com/philiplaureano/LinFu
C# | 358 lines | 270 code | 72 blank | 16 comment | 4 complexity | 9fdfd7e98162271f8549c9b4300154fb MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Linq;
  4using System.Reflection;
  5using LinFu.IoC;
  6using LinFu.IoC.Configuration;
  7using LinFu.IoC.Configuration.Interfaces;
  8using LinFu.IoC.Interfaces;
  9using Moq;
 10using Xunit;
 11using SampleLibrary;
 12using SampleLibrary.IOC;
 13
 14namespace LinFu.UnitTests.IOC
 15{
 16    public class ResolutionTests
 17    {
 18        private static ServiceContainer GetContainerWithMockSampleServices()
 19        {
 20            var mockSampleService = new Mock<ISampleService>();
 21            var container = new ServiceContainer();
 22
 23            // Add a bunch of dummy services
 24            for (var i = 0; i < 10; i++)
 25            {
 26                var serviceName = string.Format("Service{0}", i + 1);
 27                container.AddService(serviceName, mockSampleService.Object);
 28            }
 29
 30            var services = container.GetServices<ISampleService>();
 31            Assert.True(services.Count() == 10);
 32
 33            foreach (var service in services) Assert.Same(mockSampleService.Object, service);
 34
 35            return container;
 36        }
 37
 38        [Fact]
 39        public void ShouldAutoCreateClassWithServiceArrayAsConstructorArgument()
 40        {
 41            var container = GetContainerWithMockSampleServices();
 42            var result = container.AutoCreate(typeof(SampleClassWithServiceArrayAsConstructorArgument))
 43                as SampleClassWithServiceArrayAsConstructorArgument;
 44
 45            Assert.NotNull(result);
 46            Assert.True(result.Services.Length > 0);
 47        }
 48
 49        [Fact]
 50        public void ShouldAutoCreateClassWithServiceEnumerableAsConstructorArgument()
 51        {
 52            var container = GetContainerWithMockSampleServices();
 53            var result = container.AutoCreate(typeof(SampleClassWithServiceEnumerableAsConstructorArgument))
 54                as SampleClassWithServiceEnumerableAsConstructorArgument;
 55
 56            Assert.NotNull(result);
 57            Assert.NotNull(result.Services);
 58            Assert.True(result.Services.Count() > 0);
 59        }
 60
 61        [Fact]
 62        public void ShouldBeAbleToAutoCreateClassUsingGenericAutoCreateCall()
 63        {
 64            var container = GetContainerWithMockSampleServices();
 65            var result = container.AutoCreate<SampleClassWithServiceArrayAsConstructorArgument>();
 66
 67            Assert.NotNull(result);
 68            Assert.True(result.Services.Length > 0);
 69        }
 70
 71        [Fact]
 72        public void ShouldCallStronglyTypedFunctorInsteadOfActualFactory()
 73        {
 74            var container = new ServiceContainer();
 75
 76            Func<int, int, int> addOperation1 = (a, b) => a + b;
 77            container.AddService("Add", addOperation1);
 78
 79            Func<int, int, int, int> addOperation2 = (a, b, c) => a + b + c;
 80            container.AddService("Add", addOperation2);
 81
 82            Func<int, int, int, int, int> addOperation3 = (a, b, c, d) => a + b + c + d;
 83            container.AddService("Add", addOperation3);
 84
 85            Assert.Equal(2, container.GetService<int>("Add", 1, 1));
 86            Assert.Equal(3, container.GetService<int>("Add", 1, 1, 1));
 87            Assert.Equal(4, container.GetService<int>("Add", 1, 1, 1, 1));
 88        }
 89
 90        [Fact]
 91        public void ShouldConstructParametersFromContainer()
 92        {
 93            var targetConstructor = typeof(SampleClassWithMultipleConstructors).GetConstructor(new[]
 94            {
 95                typeof
 96                (
 97                    ISampleService
 98                ),
 99                typeof
100                (
101                    ISampleService
102                )
103            });
104
105            // Initialize the container
106            var mockSampleService = new Mock<ISampleService>();
107            IServiceContainer container = new ServiceContainer();
108            container.AddService(mockSampleService.Object);
109            container.AddService<IArgumentResolver>(new ArgumentResolver());
110
111            // Generate the arguments using the target constructor
112            var arguments = targetConstructor.ResolveArgumentsFrom(container);
113            Assert.Same(arguments[0], mockSampleService.Object);
114            Assert.Same(arguments[1], mockSampleService.Object);
115        }
116
117        [Fact]
118        public void ShouldConvertParameterInfoIntoPredicateThatChecksIfParameterTypeExistsAsService()
119        {
120            // Initialize the container so that it contains
121            // an instance of ISampleService
122            var mockSampleService = new Mock<ISampleService>();
123            var container = new ServiceContainer();
124
125            container.AddService(mockSampleService.Object);
126
127            var constructor = typeof(SampleClassWithSingleArgumentConstructor)
128                .GetConstructor(new[] {typeof(ISampleService)});
129
130            var parameters = constructor.GetParameters();
131            var firstParameter = parameters.First();
132
133            Assert.NotNull(firstParameter);
134
135            var mustExist = firstParameter.ParameterType.MustExistInContainer();
136            Assert.True(mustExist(container));
137        }
138
139        [Fact]
140        public void ShouldConvertTypeIntoPredicateThatChecksIfTypeExistsInContainerAsEnumerableSetOfServices()
141        {
142            var container = GetContainerWithMockSampleServices();
143
144            var predicate = typeof(IEnumerable<ISampleService>)
145                .ExistsAsEnumerableSetOfServices();
146
147            Assert.True(predicate(container));
148        }
149
150        [Fact]
151        public void ShouldConvertTypeIntoPredicateThatChecksIfTypeExistsInContainerAsServiceArray()
152        {
153            var container = GetContainerWithMockSampleServices();
154
155            var predicate = typeof(ISampleService[])
156                .ExistsAsServiceArray();
157
158            Assert.True(predicate(container));
159        }
160
161        [Fact]
162        public void ShouldCreateTypeWithAdditionalParameters()
163        {
164            var mockSampleService = new Mock<ISampleService>();
165            IServiceContainer container = new ServiceContainer();
166
167            // Add an ISampleService instance
168            container.AddService(mockSampleService.Object);
169
170            var resolver = container.GetService<IMemberResolver<ConstructorInfo>>();
171            Assert.NotNull(resolver);
172
173            var instance =
174                container.AutoCreate(typeof(SampleClassWithAdditionalArgument), 42) as
175                    SampleClassWithAdditionalArgument;
176            Assert.NotNull(instance);
177            Assert.True(instance.Argument == 42);
178        }
179
180        [Fact]
181        public void ShouldInjectConstructorWithNamedParameterTypes()
182        {
183            var mockDefaultSampleService = new Mock<ISampleService>();
184            var mockOtherSampleService = new Mock<ISampleService>();
185            var container = new ServiceContainer();
186
187            // Add the default service
188            container.AddService(mockDefaultSampleService.Object);
189
190            // Add the expected service instance
191            container.AddService("OtherService", mockOtherSampleService.Object);
192
193            var serviceInstance =
194                (SampleClassWithNamedParameters) container.AutoCreate(typeof(SampleClassWithNamedParameters));
195
196            Assert.Equal(mockOtherSampleService.Object, serviceInstance.ServiceInstance);
197        }
198
199        [Fact]
200        public void ShouldInstantiateClassWithNonServiceArguments()
201        {
202            var container = new ServiceContainer();
203            container.AddDefaultServices();
204
205            container.AddService(typeof(SampleClassWithNonServiceArgument), typeof(SampleClassWithNonServiceArgument));
206
207            var text = "Hello, World!";
208            string serviceName = null;
209            var result = container.GetService<SampleClassWithNonServiceArgument>(serviceName, text);
210
211            Assert.NotNull(result);
212            Assert.True(result.Value == text);
213        }
214
215        [Fact]
216        public void ShouldInstantiateClassWithServiceArrayAsConstructorArgument()
217        {
218            var container = GetContainerWithMockSampleServices();
219            container.AddService(typeof(SampleClassWithServiceArrayAsConstructorArgument),
220                typeof(SampleClassWithServiceArrayAsConstructorArgument));
221
222            var result = container.GetService(typeof(SampleClassWithServiceArrayAsConstructorArgument)) as
223                SampleClassWithServiceArrayAsConstructorArgument;
224
225            Assert.NotNull(result);
226
227            Assert.NotNull(result);
228            Assert.NotNull(result.Services);
229            Assert.True(result.Services.Count() > 0);
230        }
231
232        [Fact]
233        public void ShouldInstantiateClassWithServiceEnumerableAsConstructorArgument()
234        {
235            var container = GetContainerWithMockSampleServices();
236            container.AddService(typeof(SampleClassWithServiceEnumerableAsConstructorArgument),
237                typeof(SampleClassWithServiceEnumerableAsConstructorArgument));
238
239            var result =
240                container.GetService(typeof(SampleClassWithServiceEnumerableAsConstructorArgument)) as
241                    SampleClassWithServiceEnumerableAsConstructorArgument;
242
243            Assert.NotNull(result);
244
245            Assert.NotNull(result);
246            Assert.NotNull(result.Services);
247            Assert.True(result.Services.Count() > 0);
248        }
249
250        [Fact]
251        public void ShouldInstantiateObjectWithConstructorAndArguments()
252        {
253            var targetConstructor = typeof(SampleClassWithMultipleConstructors).GetConstructor(new[]
254            {
255                typeof
256                (
257                    ISampleService
258                ),
259                typeof
260                (
261                    ISampleService
262                )
263            });
264
265            // Create the method arguments
266            var mockSampleService = new Mock<ISampleService>();
267            var arguments = new object[] {mockSampleService.Object, mockSampleService.Object};
268
269            // Initialize the container
270            IServiceContainer container = new ServiceContainer();
271            container.AddDefaultServices();
272
273            var constructorInvoke = container.GetService<IMethodInvoke<ConstructorInfo>>();
274            var result = constructorInvoke.Invoke(null, targetConstructor, arguments);
275
276            Assert.NotNull(result);
277            Assert.Equal(typeof(SampleClassWithMultipleConstructors), result.GetType());
278        }
279
280        [Fact]
281        public void ShouldReportThatServiceExistsForStronglyTypedFunctor()
282        {
283            var container = new ServiceContainer();
284
285            Func<int, int, int> addOperation1 = (a, b) => a + b;
286            container.AddService("Add", addOperation1);
287
288            Assert.True(container.Contains("Add", typeof(int), 1, 1));
289        }
290
291        [Fact]
292        public void ShouldResolveClassWithMultipleNonServiceArgumentConstructors()
293        {
294            IServiceContainer container = new ServiceContainer();
295            container.AddDefaultServices();
296            container.AddService("ClassWithMultipleNonServiceArgumentConstructors",
297                typeof(ISampleService), typeof(SampleClassWithMultipleNonServiceArgumentConstructors),
298                LifecycleType.OncePerRequest);
299
300            // Match the correct constructor
301            var sampleService = container.GetService<ISampleService>("ClassWithMultipleNonServiceArgumentConstructors",
302                "test", 42, SampleEnum.One, (decimal) 3.14, 42);
303            Assert.NotNull(sampleService);
304        }
305
306        [Fact]
307        public void ShouldResolveConstructorWithAdditionalArgument()
308        {
309            var mockSampleService = new Mock<ISampleService>();
310            IServiceContainer container = new ServiceContainer();
311
312            // Add an ISampleService instance
313            container.AddService(mockSampleService.Object);
314            container.AddDefaultServices();
315
316            var resolver = container.GetService<IMemberResolver<ConstructorInfo>>();
317            Assert.NotNull(resolver);
318
319            // The resolver should return the constructor
320            // with the following signature: Constructor(ISampleService, int)
321            var expectedConstructor =
322                typeof(SampleClassWithAdditionalArgument).GetConstructor(new[] {typeof(ISampleService), typeof(int)});
323            Assert.NotNull(expectedConstructor);
324
325
326            var context = new MethodFinderContext(42);
327            var result = resolver.ResolveFrom(typeof(SampleClassWithAdditionalArgument), container, context);
328            Assert.Same(expectedConstructor, result);
329        }
330
331        [Fact]
332        public void ShouldResolveConstructorWithMostResolvableParametersFromContainer()
333        {
334            var mockSampleService = new Mock<ISampleService>();
335            IServiceContainer container = new ServiceContainer();
336
337            // Add an ISampleService instance
338            container.AddService(mockSampleService.Object);
339            container.AddDefaultServices();
340            var resolver = container.GetService<IMemberResolver<ConstructorInfo>>();
341            Assert.NotNull(resolver);
342
343            // The resolver should return the constructor with two ISampleService parameters
344            var expectedConstructor =
345                typeof(SampleClassWithMultipleConstructors).GetConstructor(new[]
346                {
347                    typeof(ISampleService),
348                    typeof(ISampleService)
349                });
350            Assert.NotNull(expectedConstructor);
351
352            var finderContext = new MethodFinderContext(new Type[0], new object[0], null);
353            var result = resolver.ResolveFrom(typeof(SampleClassWithMultipleConstructors), container,
354                finderContext);
355            Assert.Same(expectedConstructor, result);
356        }
357    }
358}