PageRenderTime 84ms CodeModel.GetById 40ms app.highlight 18ms RepoModel.GetById 22ms app.codeStats 0ms

/src/UnitTests/IOC/Configuration/LoaderAttributeTests.cs

http://github.com/philiplaureano/LinFu
C# | 319 lines | 220 code | 71 blank | 28 comment | 8 complexity | 7d2573731febf6cc7385f370e935f82b MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.IO;
  4using System.Linq;
  5using LinFu.IoC;
  6using LinFu.IoC.Configuration;
  7using LinFu.IoC.Configuration.Loaders;
  8using LinFu.IoC.Factories;
  9using LinFu.IoC.Interfaces;
 10using Moq;
 11using Xunit;
 12using SampleLibrary;
 13
 14namespace LinFu.UnitTests.IOC.Configuration
 15{
 16    public class LoaderAttributeTests
 17    {
 18        private static void TestFactoryConverterWith<TFactory>(string serviceName, Type serviceType,
 19            Type implementingType, ITypeLoader loader)
 20            where TFactory : IFactory
 21        {
 22            // The loader should initialize the container with
 23            // the particular factory type
 24            var mockContainer = new Mock<IServiceContainer>();
 25            mockContainer.Expect(container =>
 26                container.AddFactory(serviceName, serviceType, It.IsAny<IEnumerable<Type>>(),
 27                    It.Is<IFactory>(
 28                        f => f != null && f is TFactory || f is FunctorFactory)));
 29
 30            var factoryActions = loader.Load(implementingType).ToArray();
 31            Assert.NotNull(factoryActions);
 32            Assert.True(factoryActions.Count() == 1);
 33
 34            // There must be at least one factory from
 35            // the result list
 36            var firstResult = factoryActions.FirstOrDefault();
 37            Assert.NotNull(firstResult);
 38
 39
 40            firstResult(mockContainer.Object);
 41
 42            mockContainer.VerifyAll();
 43        }
 44
 45        [Fact]
 46        public void FactoryAttributeLoaderMustInjectOpenGenericServiceTypeIntoContainer()
 47        {
 48            var mockContainer = new Mock<IServiceContainer>();
 49            var serviceType = typeof(ISampleGenericService<>);
 50            var mockPostProcessors = new Mock<IList<IPostProcessor>>();
 51            var mockPreProcessors = new Mock<IList<IPreProcessor>>();
 52
 53            ITypeLoader loader = new FactoryAttributeLoader();
 54            var actions = loader.Load(typeof(SampleOpenGenericFactory));
 55
 56
 57            // The loader should load the mock container
 58            // using the generic open type as the service type
 59            mockContainer.Expect(container => container.PostProcessors)
 60                .Returns(mockPostProcessors.Object);
 61
 62            mockContainer.Expect(container => container.PreProcessors)
 63                .Returns(mockPreProcessors.Object);
 64
 65            mockContainer.Expect(container => container.AddFactory(null,
 66                serviceType, It.IsAny<IEnumerable<Type>>(),
 67                It.IsAny<SampleOpenGenericFactory>()));
 68
 69            // The postprocessor list should have an additional element added
 70            mockPostProcessors.Expect(p => p.Add(It.IsAny<IPostProcessor>()));
 71
 72            // The preprocessor list should have an additional element added as well
 73            mockPreProcessors.Expect(p => p.Add(It.IsAny<IPreProcessor>()));
 74
 75            Action<IServiceContainer> applyActions =
 76                container =>
 77                {
 78                    foreach (var action in actions) action(container);
 79                };
 80
 81            applyActions(mockContainer.Object);
 82
 83            // Apply the actions to a real container and verify
 84            // it with the expected service instance
 85            var realContainer = new ServiceContainer();
 86            applyActions(realContainer);
 87        }
 88
 89        [Fact]
 90        public void FactoryAttributeLoaderMustInjectStronglyTypedFactoryIntoContainer()
 91        {
 92            var container = new ServiceContainer();
 93            var serviceType = typeof(ISampleService);
 94
 95            ITypeLoader loader = new FactoryAttributeLoader();
 96            var actions = loader.Load(typeof(SampleStronglyTypedFactory));
 97
 98            // The factory loader should return a set of actions
 99            // that will inject that custom factory into the container
100            // itself
101            foreach (var action in actions) action(container);
102
103            Assert.True(container.Contains(serviceType));
104        }
105
106        [Fact]
107        public void FactoryAttributeLoaderMustInjectUnnamedCustomFactoryIntoContainer()
108        {
109            var mockContainer = new Mock<IServiceContainer>();
110            var mockPreProcessors = new Mock<IList<IPreProcessor>>();
111            var serviceType = typeof(ISampleService);
112            string serviceName = null;
113
114            // The container should add the expected
115            // factory type
116            mockContainer.Expect(
117                container => container.AddFactory(serviceName, serviceType, It.IsAny<IEnumerable<Type>>(),
118                    It.IsAny<SampleFactory>()));
119
120            // The factory attribute loader will add the custom
121            // factory to the preprocessors collection
122            mockContainer.Expect(container => container.PreProcessors)
123                .Returns(mockPreProcessors.Object);
124
125            mockPreProcessors.Expect(p => p.Add(It.IsAny<IPreProcessor>()));
126
127            ITypeLoader loader = new FactoryAttributeLoader();
128            var actions = loader.Load(typeof(SampleFactory));
129
130            // The factory loader should return a set of actions
131            // that will inject that custom factory into the container
132            // itself
133            foreach (var action in actions) action(mockContainer.Object);
134
135            mockContainer.VerifyAll();
136        }
137
138        [Fact]
139        public void LoaderMustLoadSingletonTypesAndThoseTypesMustBeTheSameInstance()
140        {
141            var location = typeof(SamplePostProcessor).Assembly.Location ?? string.Empty;
142            var loader = new Loader();
143            var directory = Path.GetDirectoryName(location);
144
145            // Load the default plugins first
146            loader.LoadDirectory(AppDomain.CurrentDomain.BaseDirectory, "LinFu*.dll");
147
148            // Load the sample library
149            loader.LoadDirectory(directory, Path.GetFileName(location));
150
151            var filename = Path.Combine(directory, location);
152            Assert.True(File.Exists(filename));
153
154            var container = new ServiceContainer();
155
156            loader.LoadInto(container);
157
158            var first = container.GetService<ISampleService>("First");
159            var second = container.GetService<ISampleService>("First");
160
161            Assert.NotNull(first);
162            Assert.NotNull(second);
163            Assert.Same(first, second);
164        }
165
166        [Fact]
167        public void LoaderMustLoadTheCorrectOncePerRequestTypes()
168        {
169            var location = typeof(SamplePostProcessor).Assembly.Location ?? string.Empty;
170            var loader = new Loader();
171            var directory = Path.GetDirectoryName(location);
172
173            // Load the default plugins first
174            loader.LoadDirectory(AppDomain.CurrentDomain.BaseDirectory, "LinFu*.dll");
175
176            // Load the sample library
177            loader.LoadDirectory(directory, Path.GetFileName(location));
178
179            var filename = Path.Combine(directory, location);
180            Assert.True(File.Exists(filename));
181
182            var container = new ServiceContainer();
183
184            loader.LoadInto(container);
185
186            var first = container.GetService<ISampleService>("FirstOncePerRequestService");
187            var second = container.GetService<ISampleService>("SecondOncePerRequestService");
188
189            Assert.NotNull(first);
190            Assert.NotNull(second);
191            Assert.True(first.GetType() == typeof(FirstOncePerRequestService));
192            Assert.True(second.GetType() == typeof(SecondOncePerRequestService));
193        }
194
195        [Fact]
196        public void LoaderMustLoadTheCorrectSingletonTypes()
197        {
198            var location = typeof(SamplePostProcessor).Assembly.Location ?? string.Empty;
199            var loader = new Loader();
200            var directory = Path.GetDirectoryName(location);
201
202            // Load the default plugins first
203            loader.LoadDirectory(AppDomain.CurrentDomain.BaseDirectory, "LinFu*.dll");
204
205            // Load the sample library
206            loader.LoadDirectory(directory, Path.GetFileName(location));
207
208            var filename = Path.Combine(directory, location);
209            Assert.True(File.Exists(filename));
210
211            var container = new ServiceContainer();
212
213            loader.LoadInto(container);
214
215            var first = container.GetService<ISampleService>("First");
216            var second = container.GetService<ISampleService>("Second");
217
218            Assert.NotNull(first);
219            Assert.NotNull(second);
220            Assert.True(first.GetType() == typeof(FirstSingletonService));
221            Assert.True(second.GetType() == typeof(SecondSingletonService));
222        }
223
224        [Fact]
225        public void NamedOncePerRequestFactoryMustBeCreatedFromTypeWithImplementsAttribute()
226        {
227            var implementingType = typeof(NamedOncePerRequestSampleService);
228            var serviceType = typeof(ISampleService);
229            var converter = new ImplementsAttributeLoader();
230
231            TestFactoryConverterWith<OncePerRequestFactory<ISampleService>>("MyService",
232                serviceType, implementingType, converter);
233        }
234
235        [Fact]
236        public void NamedOncePerThreadFactoryMustBeCreatedFromTypeWithImplementsAttribute()
237        {
238            TestFactoryConverterWith<OncePerThreadFactory<ISampleService>>("MyService",
239                typeof(ISampleService),
240                typeof(NamedOncePerThreadSampleService),
241                new ImplementsAttributeLoader());
242        }
243
244        [Fact]
245        public void NamedSingletonFactoryMustBeCreatedFromTypeWithImplementsAttribute()
246        {
247            TestFactoryConverterWith<SingletonFactory<ISampleService>>("MyService",
248                typeof(ISampleService),
249                typeof(NamedSingletonSampleService),
250                new ImplementsAttributeLoader());
251        }
252
253        [Fact]
254        public void OncePerRequestFactoryMustBeCreatedFromTypeWithImplementsAttribute()
255        {
256            var implementingType = typeof(OncePerRequestSampleService);
257            var serviceType = typeof(ISampleService);
258            var converter = new ImplementsAttributeLoader();
259
260            TestFactoryConverterWith<OncePerRequestFactory<ISampleService>>(null,
261                serviceType, implementingType, converter);
262        }
263
264        [Fact]
265        public void OncePerThreadFactoryMustBeCreatedFromTypeWithImplementsAttribute()
266        {
267            TestFactoryConverterWith<OncePerThreadFactory<ISampleService>>(null,
268                typeof(ISampleService),
269                typeof(OncePerThreadSampleService),
270                new ImplementsAttributeLoader());
271        }
272
273        [Fact]
274        public void ServicesCreatedFromCustomOpenGenericFactoryMustInvokeIInitialize()
275        {
276            var mockFactory = new Mock<IFactory>();
277            var serviceInstance = new SampleGenericImplementation<int>();
278
279            mockFactory.Expect(f => f.CreateInstance(It.IsAny<IFactoryRequest>()))
280                .Returns(serviceInstance);
281
282            var container = new ServiceContainer();
283
284
285            container.LoadFrom(AppDomain.CurrentDomain.BaseDirectory, "LinFu*.dll");
286            container.AddFactory("MyService", typeof(ISampleGenericService<>), mockFactory.Object);
287
288            var result = container.GetService<ISampleGenericService<int>>("MyService");
289            var areSame = ReferenceEquals(serviceInstance, result);
290
291            Assert.Same(serviceInstance, result);
292
293            // Make sure that the IInitialize instance is called
294            // on the sample class
295            Assert.True(serviceInstance.Called);
296
297            mockFactory.VerifyAll();
298        }
299
300        [Fact]
301        public void ShouldInjectInternallyVisibleServiceTypeMarkedWithImplementsAttribute()
302        {
303            var container = new ServiceContainer();
304            container.LoadFromBaseDirectory("*.dll");
305
306            var service = container.GetService<ISampleService>("internal");
307            Assert.NotNull(service);
308        }
309
310        [Fact]
311        public void SingletonFactoryMustBeCreatedFromTypeWithImplementsAttribute()
312        {
313            TestFactoryConverterWith<SingletonFactory<ISampleService>>(null,
314                typeof(ISampleService),
315                typeof(SingletonSampleService),
316                new ImplementsAttributeLoader());
317        }
318    }
319}