views:

36

answers:

0

When using the ArrayResolver, if I register multiple dependencies that implement the same interface and I have registered classes that depend on an array of these dependencies, one would expect ServiceOverrides to be respected and allow control over which dependencies are injected into the contructors. Instead, I have seen and written tests that show every dependency is injected into the registered classes contructors.

using System.Linq;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.Resolvers.SpecializedResolvers;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using NUnit.Framework;

namespace ServiceFramework.UnitTests
{
    public class ArrayResolver_ServiceOverridesNotRespected
    {
        private class TestInstaller : IWindsorInstaller
        {
            public void Install(IWindsorContainer container, IConfigurationStore store)
            {
                container.Register(
                    Component.For<IDependency>().ImplementedBy<Foo>().Named("foo"),
                    Component.For<IDependency>().ImplementedBy<Bar>().Named("bar"),
                    Component.For<IDependency>().ImplementedBy<Baz>().Named("baz"),
                    Component.For<IDependOnArray>().ImplementedBy<DependsOnArray>().Named("InjectAll"),
                    Component.For<IDependOnArray>().ImplementedBy<DependsOnArray>().Named("InjectFooOnly").ServiceOverrides(
                        ServiceOverride.ForKey("steps").Eq(new[] {"foo"})),
                    Component.For<IDependOnArray>().ImplementedBy<DependsOnArray>().Named("InjectFooAndBarOnly").ServiceOverrides(
                        ServiceOverride.ForKey("steps").Eq(new[] {"foo", "bar"})));
            }
        }

        public interface IDependency
        {
        }

        public class Foo : IDependency
        {
        }

        public class Bar : IDependency
        {
        }

        public class Baz : IDependency
        {
        }

        public interface IDependOnArray
        {
            IDependency[] GetDependencies();
        }

        public class DependsOnArray : IDependOnArray
        {
            private readonly IDependency[] _steps;
            public DependsOnArray(IDependency[] steps)
            {
                _steps = steps;
            }

            public IDependency[] GetDependencies()
            {
                return _steps;
            }
        }

        [Test]
        public void InjectFooOnly_WithoutArrayResolver()
        {
            using (var container = new WindsorContainer())
            {
                container.Install(new TestInstaller());
                var fooItemTest = container.Resolve<IDependOnArray>("InjectFooOnly");
                var dependencies = fooItemTest.GetDependencies().Select(d => d.GetType()).ToList();
                Assert.That(dependencies, Has.Count.EqualTo(1));
                Assert.That(dependencies, Has.Member(typeof(Foo)));
            }
        }

        [Test]
        [ExpectedException(typeof(AssertionException))]
        public void InjectFooOnly_WithArrayResolver()
        {
            using (var container = new WindsorContainer())
            {
                container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel, true));
                container.Install(new TestInstaller());
                var fooItemTest = container.Resolve<IDependOnArray>("InjectFooOnly");
                var dependencies = fooItemTest.GetDependencies().Select(d => d.GetType()).ToList();
                Assert.That(dependencies, Has.Count.EqualTo(1));
                Assert.That(dependencies, Has.Member(typeof(Foo)));
            }
        }

        [Test]
        public void InjectFooAndBarOnly_WithoutArrayResolver()
        {
            using (var container = new WindsorContainer())
            {
                container.Install(new TestInstaller());
                var fooItemTest = container.Resolve<IDependOnArray>("InjectFooAndBarOnly");
                var dependencies = fooItemTest.GetDependencies().Select(d => d.GetType()).ToList();
                Assert.That(dependencies, Has.Count.EqualTo(2));
                Assert.That(dependencies, Has.Member(typeof(Foo)));
                Assert.That(dependencies, Has.Member(typeof(Bar)));
            }
        }

        [Test]
        [ExpectedException(typeof(AssertionException))]
        public void InjectFooAndBarOnly_WithArrayResolver()
        {
            using (var container = new WindsorContainer())
            {
                container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel, true));
                container.Install(new TestInstaller());
                var fooItemTest = container.Resolve<IDependOnArray>("InjectFooAndBarOnly");
                var dependencies = fooItemTest.GetDependencies().Select(d => d.GetType()).ToList();
                Assert.That(dependencies, Has.Count.EqualTo(2));
                Assert.That(dependencies, Has.Member(typeof(Foo)));
                Assert.That(dependencies, Has.Member(typeof(Bar)));
            }
        }

        [Test]
        public void InjectAll()
        {
            using (var container = new WindsorContainer())
            {
                container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel, true));
                container.Install(new TestInstaller());
                var fooItemTest = container.Resolve<IDependOnArray>("InjectAll");
                var dependencies = fooItemTest.GetDependencies().Select(d => d.GetType()).ToList();
                Assert.That(dependencies, Has.Count.EqualTo(3));
                Assert.That(dependencies, Has.Member(typeof(Foo)));
                Assert.That(dependencies, Has.Member(typeof(Bar)));
                Assert.That(dependencies, Has.Member(typeof(Baz)));
            }
        }
    }
}

related questions