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)));
}
}
}
}