santiagoIT
santiagoIT

Reputation: 9431

How can I achieve this in Windsor Castle? (Migrating from StructureMap)

I need to modify an existing web app to use Castle.Windsor as IOC container. It was originally developed with StructureMap.

I am stuck with the following problem.

Lets say I have registered a couple of interfaces and their corresponding implementations:

IFoo -> Foo
IBar -> Bar

Calling container.Resolve<IFoo>() or container.Resolve<IBar>() works just fine. This means that the services are registered correctly.

I have a Web Api class with dependencies on other services, such as IFoo

public class BadRequestErrorHandler : HttpErrorHandler
{
    // services
    public BadRequestErrorHandler(IFoo foo) {...} // has dependency on IFoo
}

In StructureMap I can call:

var test = ObjectFactory.GetInstance<BadRequestErrorHandler>();

this will resolve the IFoo dependency.

Now this does not work with windsor.

How can this be achieved with windsor?

Thanks!

* EDIT * I was just able to make it work by explicitely registering the BadRequestErrorHandler.

container.Register(Component.For<BadRequestErrorHandler>());

I am just hoping there is a better way to achieve this, that does not involve registering classes that have dependencies. I have a bunch of them...

* EDIT 2 **

To ease the pain, I added a special method to deal with these concrete types.

public T GetInstanceWithAutoRegister<T>()
{
    if (container.Kernel.GetHandler(typeof(T)) == null)
    {
        container.Register(Component.For<T>());
    }
    return container.Resolve<T>();
}

public object GetInstanceWithAutoRegister(Type pluginType)
{
    if (container.Kernel.GetHandler(pluginType) == null)
    {
        container.Register(Component.For(pluginType));
    }
    return container.Resolve(pluginType);
}

not ideal, but at least better than having to explicetly register each type. Hope someone has a better solution

Upvotes: 0

Views: 279

Answers (1)

mookid8000
mookid8000

Reputation: 18628

You can achieve what you want by registering an ILazyComponentLoader which is a hook that gets called by Windsor as a "last resort" when a component cannot be resolved.

In your case, the implementation would probably look somewhat like this:

public class JustLetWindsorResolveAllConcreteTypes : ILazyComponentLoader
{
    public IRegistration Load(string key, Type service)
    {
        return Component.For(service);
    }
}

-and then it should be registered as such:

container.Register(Component.For<ILazyComponentLoader>()
         .ImplementedBy<JustLetWindsorResolveAllConcreteTypes>());

You can read more about it in the docs.

Upvotes: 1

Related Questions