[TestFixture]
[Category(TestCategories.UnitTest)]
public class UnregisteredClassResolverFacilityDepth3IssueTest
{
[Test]
public void TestUnregisteredOptionalDependencyOnUnregisteredClass2()
{
var container = new WindsorContainer();
container.Register(Component.For<ILazyComponentLoader>().ImplementedBy<UnregisteredClassResolver>());
// container.Register(Component.For<Baz>()); // <-- makes it work
// container.Resolve<Baz>(); <-- makes it work
// container.Register(Component.For<Bar>()); // <-- does not make it work
var bar = container.Resolve<Bar>();
Assert.AreEqual("Baz Foo Bar", bar.ToString());
}
public class Bar
{
public Foo Foo { get; set; }
public override string ToString()
{
return Foo + " Bar";
}
}
public class Baz
{
public override string ToString()
{
return "Baz";
}
}
public class Foo
{
private readonly Baz _baz;
public Foo(Baz baz)
{
_baz = baz;
}
public override string ToString()
{
return _baz + " Foo";
}
}
private class UnregisteredClassResolver : ILazyComponentLoader
{
public IRegistration Load(string name, Type service, IDictionary arguments)
{
return Component.For(service);
}
}
}
It defines 3 classe: Foo, Bar and Baz. Bar has a property Foo of type Foo and Foo in turn takes Baz as a constructor parameter. In other words Bar depends on Foo (optionally) and Foo depends on Baz.
At the bottom is a lazy loader that simply registers any service it gets (for testing purposes).
When the test is run the result of taking ToString() on the resolved Bar should be "Baz Foo Bar", however the result is simply " Bar" as the Foo dependency in Bar is never realized. If the commented-out line in commented-in (i.e. the line explicitly resolving Baz), then it works, and stepping through it in the debugger shows that the lazy loader is called first for Bar, then for Foo but then not for Baz. It appears that Windsor sees that Foo has a non-registered dependency and is optional and thus decides to not see if its possible to resolve it.
Its worth noting that it makes difference whether Bar is explicitly registered or not.
Is this a bug or is there something that needs to be done to ensure that lazy loading works properly for optional dependencies?
/kim