예제 #1
0
        public void ExtendedActivator_ShouldThrowOnNonInterfaceArguments()
        {
            ConstructorInfo ctor = typeof(MyClass).GetConstructor(new[] { typeof(IDisposable), typeof(IList), typeof(int) });

            //
            // Sima Get() hivas nem fog mukodni (nem interface parameter).
            //

            Assert.Throws <ArgumentException>(() => ServiceActivator.Get(ctor), Resources.INVALID_CONSTRUCTOR);

            //
            // Ne mock-oljuk az injector-t h a megfelelo kiveteleket kapjuk
            //

            using (IServiceContainer container = new ServiceContainer())
            {
                IInjector injector = container
                                     .Factory <IDisposable>(i => new Disposable(), Lifetime.Scoped)
                                     .Factory <IList>(i => new List <object>(), Lifetime.Scoped)
                                     .CreateInjector();

                //
                // Ez mukodne viszont nem adtuk meg a nem interface parametert.
                //

                Assert.Throws <ArgumentException>(() => ServiceActivator.GetExtended(ctor).Invoke(injector, new Dictionary <string, object>(0)), Resources.PARAMETER_NOT_AN_INTERFACE);
            }
        }
        /// <summary>
        /// Instantiates the given class.
        /// </summary>
        /// <param name="self">The injector itself.</param>
        /// <param name="class">The class to be instantiated.</param>
        /// <param name="explicitArgs">The explicit arguments (in the form of [parameter name - parameter value]). Explicit arguments won't be resolved by the injector.</param>
        /// <returns>The new instance.</returns>
        /// <remarks>
        /// <list type="bullet">
        /// <item><description>The <paramref name="class"/> you passed must have only one public constructor or you must annotate the appropriate one with the <see cref="ServiceActivatorAttribute"/>.</description></item>
        /// <item><description>Constructor parameteres that are not present in the <paramref name="explicitArgs"/> are treated as a normal dependency.</description></item>
        /// <item><description>The caller is responsible for freeing the returned instance.</description></item>
        /// </list>
        /// </remarks>
        /// <exception cref="ServiceNotFoundException">One or more dependecies could not be found.</exception>
        public static object Instantiate(this IInjector self, Type @class, IReadOnlyDictionary <string, object?>?explicitArgs = null)
        {
            Ensure.Parameter.IsNotNull(self, nameof(self));
            Ensure.Parameter.IsNotNull(@class, nameof(@class));

            return(ServiceActivator.GetExtended(@class).Invoke(self, explicitArgs ?? new Dictionary <string, object?>(0)));
        }
예제 #3
0
        public void ExtendedActivator_ExplicitArgumentsMayContainNonInterfaceValues()
        {
            const int TEN = 10;

            ConstructorInfo ctor = typeof(MyClass).GetConstructor(new[] { typeof(IDisposable), typeof(IList), typeof(int) });

            var mockInjector = new Mock <IInjector>(MockBehavior.Strict);

            mockInjector
            .Setup(i => i.Get(It.IsAny <Type>(), It.IsAny <string>()))
            .Returns <Type, string>((type, name) => null);

            MyClass obj = ServiceActivator.GetExtended(ctor).Invoke(mockInjector.Object, new Dictionary <string, object> {
                { "int", TEN }
            }) as MyClass;

            Assert.That(obj, Is.Not.Null);
            Assert.That(obj.Int, Is.EqualTo(TEN));
        }
예제 #4
0
        public void ExtendedActivator_ShouldHandleOptionalArguments()
        {
            var mockInjector = new Mock <IInjector>(MockBehavior.Strict);

            mockInjector
            .Setup(i => i.Get(typeof(IList <IDictionary>), null))
            .Returns(new List <IDictionary>());
            mockInjector
            .Setup(i => i.TryGet(typeof(IDisposable), null))
            .Returns(null);

            Func <IInjector, IReadOnlyDictionary <string, object>, object> factory = ServiceActivator
                                                                                     .GetExtended(typeof(MyInterceptor));

            Assert.DoesNotThrow(() => factory.Invoke(mockInjector.Object, new Dictionary <string, object>()));

            mockInjector.Verify(i => i.Get(typeof(IList <IDictionary>), null), Times.Once);
            mockInjector.Verify(i => i.TryGet(typeof(IDisposable), null), Times.Once);
        }
예제 #5
0
        public void ExtendedActivator_ShouldHandleExplicitArguments()
        {
            var mockInjector = new Mock <IInjector>(MockBehavior.Strict);

            mockInjector.Setup(i => i.Get(It.IsAny <Type>(), It.IsAny <string>()));

            Func <IInjector, IReadOnlyDictionary <string, object>, object> factory = ServiceActivator
                                                                                     .GetExtended(typeof(List <string>).GetConstructor(new[] { typeof(int) }));

            object lst = factory(mockInjector.Object, new Dictionary <string, object>
            {
                { "capacity", 10 }
            });

            Assert.That(lst, Is.InstanceOf <List <string> >());
            Assert.That(((List <string>)lst).Capacity, Is.EqualTo(10));

            mockInjector.Verify(i => i.Get(It.IsAny <Type>(), It.IsAny <string>()), Times.Never);
        }
예제 #6
0
        public void GetExtended_ShouldSupportProxyTypes()
        {
            Type proxy = ProxyGenerator <IList <IDictionary>, MyInterceptor> .GetGeneratedType();

            Func <IInjector, IReadOnlyDictionary <string, object>, object> factory = ServiceActivator.GetExtended(proxy);

            var mockInjector = new Mock <IInjector>(MockBehavior.Strict);

            mockInjector
            .Setup(i => i.Get(typeof(IList <IDictionary>), null))
            .Returns(new List <IDictionary>());
            mockInjector
            .Setup(i => i.TryGet(typeof(IDisposable), null))
            .Returns(null);

            Assert.DoesNotThrow(() => factory.Invoke(mockInjector.Object, new Dictionary <string, object>()));

            mockInjector.Verify(i => i.Get(typeof(IList <IDictionary>), null), Times.Once);
            mockInjector.Verify(i => i.TryGet(typeof(IDisposable), null), Times.Once);
        }
예제 #7
0
        public void ExtendedActivator_ExplicitArgumentsShouldSuppressTheInjectorInvocation()
        {
            var mockInjector = new Mock <IInjector>(MockBehavior.Strict);

            mockInjector
            .Setup(i => i.Get(It.IsAny <Type>(), It.IsAny <string>()))
            .Returns <Type, string>((type, name) => null);

            Func <IInjector, IReadOnlyDictionary <string, object>, object> factory = ServiceActivator
                                                                                     .GetExtended(typeof(MyClass).GetConstructor(new[] { typeof(IDisposable), typeof(IList) }));

            object obj = factory(mockInjector.Object, new Dictionary <string, object>
            {
                { "dep2", null }
            });

            Assert.That(obj, Is.InstanceOf <MyClass>());

            mockInjector.Verify(i => i.Get(It.Is <Type>(t => t == typeof(IDisposable)), null), Times.Once);
            mockInjector.Verify(i => i.Get(It.Is <Type>(t => t == typeof(IList)), It.IsAny <string>()), Times.Never);
        }
예제 #8
0
        public void Activator_ShouldResolveDependencies(Type dep1, string name1, Type dep2, string name2)
        {
            var mockDisposable = new Mock <IDisposable>();

            var mockServiceFactory = new Mock <IList>();

            var mockInjector = new Mock <IInjector>(MockBehavior.Strict);

            foreach (Func <IInjector, object> activator in GetActivators(typeof(MyClass).GetConstructor(new[] { dep1, dep2 })))
            {
                mockInjector
                .Setup(i => i.Get(It.IsAny <Type>(), It.IsAny <string>()))
                .Returns <Type, string>((type, name) =>
                {
                    if (type == typeof(IDisposable) && name == name1)
                    {
                        return(mockDisposable.Object);
                    }
                    if (type == typeof(IList) && name == name2)
                    {
                        return(mockServiceFactory.Object);
                    }

                    Assert.Fail("Unknown type");
                    return(null);
                });

                MyClass instance = (MyClass)activator(mockInjector.Object);

                Assert.That(instance, Is.Not.Null);
                Assert.That(instance.Dep1, Is.SameAs(mockDisposable.Object));
                Assert.That(instance.Dep2, Is.SameAs(mockServiceFactory.Object));

                mockInjector.Verify(i => i.Get(It.Is <Type>(t => t == typeof(IDisposable)), It.Is <string>(n => n == name1)), Times.Once);
                mockInjector.Verify(i => i.Get(It.Is <Type>(t => t == typeof(IList)), It.Is <string>(n => n == name2)), Times.Once);
                mockInjector.Verify(i => i.Get(It.IsAny <Type>(), It.IsAny <string>()), Times.Exactly(2));

                mockInjector.Reset();
            }

            IEnumerable <Func <IInjector, object> > GetActivators(ConstructorInfo ctor)
            {
                Func <IInjector, Type, object> factory = ServiceActivator.Get(ctor);

                yield return(injector => factory(injector, null));

                Func <IInjector, IReadOnlyDictionary <string, object>, object> factoryEx = ServiceActivator.GetExtended(ctor);

                yield return(injector => factoryEx(injector, new Dictionary <string, object>(0)));
            }
        }
예제 #9
0
 public void GetExtended_ShouldCache()
 {
     Assert.AreSame(ServiceActivator.GetExtended(typeof(Disposable)), ServiceActivator.GetExtended(typeof(Disposable)));
     Assert.AreSame(ServiceActivator.GetExtended(typeof(Disposable).GetApplicableConstructor()), ServiceActivator.GetExtended(typeof(Disposable).GetApplicableConstructor()));
 }
예제 #10
0
 public void GetExtended_ShouldValidate()
 {
     Assert.Throws <ArgumentException>(() => ServiceActivator.GetExtended(typeof(IDisposable)), Resources.PARAMETER_NOT_A_CLASS);
     Assert.Throws <ArgumentException>(() => ServiceActivator.GetExtended(typeof(IList <>)), Resources.PARAMETER_IS_GENERIC);
     Assert.Throws <ArgumentException>(() => ServiceActivator.GetExtended(typeof(AbstractClass)), Resources.PARAMETER_IS_ABSTRACT);
 }