Resolving Interface with generic type constraint with Castle Windsor

梦想与她 提交于 2019-12-10 18:07:04

问题


Given the interface where FooRequest and FooResponse are abstract:

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

An implementation of:

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

How would I register this in Castle Windsor so I can resolve it using (where IoCContainer is a WindsorContainer:

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

to resolve an instance of MyFooHandler?


回答1:


In Castle Windsor you can use such code :

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 find registering and resolving generics pretty simple for registering and resolving generics with interfaces. There a lots of questions on castle and generics around.




回答2:


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

As far as I know Simple Injector is the only container out there which completely honours generic type constraints out-of-the-box on 99.9% of the possibilities. Autofac is also aware of generic type constraints but it is easy to create a type constraint which compiles but breaks at runtime with Autofac.

Generics are fun to work with in all cases but especially when you use Simple Injector as your container of choice, IMO. The documentation for using generics can be found here.

Because you're using generics I expect you have many closed implementations of your IFooHandler<TRequest,TResponse> interface. Registering all these implementations is a one liner with Simple Injector:

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

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

There are numerous advanced options, which you can use to greatly improve the 'SOLIDness' of your application. These can all be found in the documentation.

There is one specific one I want to mention: By registering a open generic decorator, Simple Injector is capable of retrieving instances which are decorated with this (or more) decorators. This feature makes it super easy to stick to SOLID design and still implement the most advanced scenarios and/or cross cutting concerns. Note that even in this scenario Simple Injector will look at and act accordingly to the generic type constraints and the different decorators.



来源:https://stackoverflow.com/questions/30915944/resolving-interface-with-generic-type-constraint-with-castle-windsor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!