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.

Reply via email to