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

4

假设有一个接口,其中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 实例?
2个回答

5
在Castle Windsor中,您可以使用以下代码:
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
{
...
}

因此,我发现注册和解析通用类型与接口相当简单。关于Castle和泛型还有很多问题。

1

我不熟悉Castle & Windsor,但我相信这是一个DI容器不支持的用例。

据我所知,Simple Injector 是唯一一个在99.9%的情况下完全支持泛型类型约束的容器。Autofac也意识到了泛型类型约束,但很容易创建一个在编译时可以编译但在运行时会在Autofac中出错的类型约束。

在所有情况下,使用泛型都很有趣,特别是当您将Simple Injector作为首选容器时,我的意见是如此。有关使用泛型的文档可以在此处找到。

因为你正在使用泛型,我期望你有许多封闭的实现IFooHandler<TRequest,TResponse>接口。使用Simple Injector注册所有这些实现只需要一行代码:

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

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

有许多高级选项可用于大大提高应用程序的“SOLID性”。这些都可以在文档中找到。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接