使用 Castle Windsor 解析具有泛型类型约束的接口

Resolving Interface with generic type constraint with Castle Windsor

给定 FooRequest 和 FooResponse 是抽象的接口:

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

实现:

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

我如何在 Castle Windsor 中注册它以便我可以使用(其中 IoCContainer 是 WindsorContainer:

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

解析 MyFooHandler 的实例?

我不熟悉 Castle & Windsor,但我很确定这是一个不受此 DI 容器支持的用例。

据我所知,Simple Injector 是唯一一个在 99.9% 的可能性上完全遵守开箱即用的通用类型约束的容器。 Autofac 也知道泛型类型约束,但使用 Autofac 很容易创建一个编译但在运行时中断的类型约束。

在所有情况下使用泛型都很有趣,尤其是当您使用 Simple Injector 作为您选择的容器时,IMO。可以找到使用泛型的文档 here.

因为您使用的是泛型,所以我希望您有许多 IFooHandler<TRequest,TResponse> 接口的封闭实现。注册所有这些实现是简单注入器的一个衬里:

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

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

有许多高级选项,您可以使用它们来大大改进您的应用程序 'SOLIDness'。这些都可以在文档中找到。

我想特别提到一个: 通过注册一个开放的通用装饰器,Simple Injector 能够检索用这个(或更多)装饰器装饰的实例。此功能使坚持 SOLID 设计并仍然实现最高级的场景 and/or 横切关注点变得非常容易。 请注意,即使在这种情况下,Simple Injector 也会查看泛型类型约束和不同的装饰器并据此采取行动。

在温莎城堡你可以使用这样的代码:

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
{
...
}

因此,我发现注册和解析泛型对于使用接口注册和解析泛型来说非常简单。周围有很多关于城堡和泛型的问题。