简体   繁体   中英

Is there a way to eagerly resolve all components registered with Windsor IoC container?

I have C# application where I register a few dozen interfaces with their implementation classes in the Windsor container. All these implementation classes are resolved as singletons by Windsor. The question is can I somehow make Windsor manually resolve all these stuff and wire them to create a object graph? Rather than lazy resolving that Windsor does by default when some component is request, I need to resolve them all at once for some debugging and testing purposes. Ideally I'd like to get the array of instances for all registered types. Is this possible?

The dependency graph is available through the GraphNodes property. Here's a simple demonstration:

[Test]
public void Get1()
{
    var container = new WindsorContainer();
    container.Register(Component.For<SomeClass>().LifestyleSingleton());
    container.Register(Component.For<Dependency>().LifestyleSingleton());

    var graphNodes = container.Kernel.GraphNodes;

    Assert.That(graphNodes.Length, Is.EqualTo(2));
    Assert.That(graphNodes[0].Dependents[0].ToString(), Is.EqualTo(typeof(Dependency).Name));
    Assert.That(graphNodes[1].Dependents.Length, Is.EqualTo(0));
}

You should easily be able to establish which types are "root" types by filtering out any types that are a dependency ...


UPDATE

One of the ways to create an instance from a GraphNode is to cast the GraphNode to Castle.Core.ComponentModel

[Test]
public void Resolve1()
{
    var container = new WindsorContainer();
    container.Register(Component.For<SomeClass>().LifestyleSingleton());
    container.Register(Component.For<Dependency>().LifestyleSingleton());

    var graphNodes = container.Kernel.GraphNodes;

    var name = (graphNodes[0] as ComponentModel).ComponentName.ToString();
    var type = Type.GetType(name);
    dynamic instance1 = container.Resolve(type);
    Assert.That(instance1, Is.Not.Null);
}

Usually for debugging and testing the container you may use the component handler instead of resolving the component itself.

Said so, Simon is right: when you Resolve a component, windsor creates the real instance and all its dependencies. Nothing is "deferred" unless you mean "late dependency" achived through a (typed) factory, but that's somenthing else...

The solution that uses ComponentName doesn't work. ComponentModel.Services should be used instead. Tested with version 3.3

        container.Kernel.GraphNodes
            .Cast<ComponentModel>()
            .ToList()
            .ForEach(component =>
            {
                component.Services
                    .ToList()
                    .ForEach(type =>
                    {
                        var instance = container.Resolve(type);
                        Assert.IsNotNull(instance);
                    });
            });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM