Allowing a generic type of interface with Castle Windsor

Given an interface where FooRequest and FooResponse are abstract:

 public interface IFooHandler<TRequest, TResponse> where TRequest : FooRequest where TResponse : FooResponse
{
    TResponse CheckFoo(TRequest request);
}

      

Implementation:

public class MyFooHandler :  IFooHandler<MyFooRequest, MyFooResponse>
{
    public MyFooResponse CheckFoo(MyFooRequest request)
    {
        /* check for foos */
    }
}

      

How do I register this in Castle Windsor so I can solve it using (where IoCContainer is WindsorContainer:

Global.IoCContainer.Resolve<IFooHandler<FooRequest, FooResponse>>();

      

to resolve an instance of MyFooHandler?

+3


source to share


2 answers


In Castle Windsor, you can use code like this:

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
    Component.For(typeof(IRepository<>)).ImplementedBy(typeof(Repository<>))
}
);

public class Repository<T> : IRepository<T> where T : class, IEntity
{
...
}

      



Therefore, I believe that registering and authorizing generics is quite easy to register and authorize generics with interfaces. There are a lot of questions about the lock and generics around.

+4


source


I'm not familiar with Castle and Windsor, but I'm pretty sure this is a use case that is not supported by this DI container.

As far as I know, the Simple Injector is the only container that fully complies with the typical out-of-the-box type constraints for 99.9% of the capacity. Autofac is also aware of generic type constraints, but it's easy to create a type constraint that compiles but breaks at runtime with Autofac.

Generally ubiquitous to work everywhere, but especially when you use Simple Injector as your container of choice, IMO. Documentation on using generics can be found here .

Since you are using generics, I expect you to have many private implementations of your interface IFooHandler<TRequest,TResponse>

. Registering all these implementations is one liner with Simple Injector:



var container = new Container();
container.RegisterManyForOpenGeneric(typeof(IFooHandler<,>)
                                        , Assembly.GetExecutingAssembly());

// resolve:
container.GetInstance<IFooHandler<FooRequest, FooResponse>>();

      

There are many additional options that you can use to dramatically improve the HARDNESS of your application. All of this can be found in the documentation.

There is one specific one I want to mention: By registering a public generic decorator, Simple Injector is able to retrieve instances decorated with these (or more) decorators. This feature makes it very easy to stick to SOLID and still implement the most advanced crosscut scenarios and / or problems. Note that even in this case, Simple Injector will look and act according to generic constraints and various decorators.

+1


source







All Articles