Hi
I using the ILazyComponentLoader functionality to lazily load specific
types (marked by interface or attribute) but ran into an issue with
dependencies of optional dependencies where both are registered lazily.
I have written the following self-contained (apart from the Castle libs)
nunit test to illustrate the issue:
[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
--
You received this message because you are subscribed to the Google Groups
"Castle Project Users" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/castle-project-users/-/Hro5W0RW_zUJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/castle-project-users?hl=en.