使用Castle Windsor解决具有generics类型约束的接口
给定FooRequest和FooResponse是抽象的接口:
public interface IFooHandler where TRequest : FooRequest where TResponse : FooResponse { TResponse CheckFoo(TRequest request); }
实施:
public class MyFooHandler : IFooHandler { public MyFooResponse CheckFoo(MyFooRequest request) { /* check for foos */ } }
我如何在温莎城堡注册这个,以便我可以解决它(其中IoCContainer是一个WindsorContainer:
Global.IoCContainer.Resolve<IFooHandler>();
解决MyFooHandler的实例?
在温莎城堡,你可以使用这样的代码:
public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register( Component.For(typeof(IRepository<>)).ImplementedBy(typeof(Repository<>)) } ); public class Repository : IRepository where T : class, IEntity { ... }
因此,我发现注册和解析generics非常简单,可以通过接口注册和解析generics。 关于城堡和仿制品的问题很多。
我对Castle&Windsor不熟悉,但我很确定这是一个DI容器不支持的用例。
据我所知, Simple Injector是唯一一个完全遵循99.9%可能性的开箱即用通用类型约束的容器。 Autofac也知道generics类型约束,但很容易创建一个类型约束,它在运行时使用Autofac进行编译但会中断。
在所有情况下,generics都很有趣,但尤其是当您使用Simple Injector作为您选择的容器IMO时。 可以在此处找到使用generics的文档。
因为您正在使用generics,所以我希望您有许多关闭IFooHandler
接口的实现。 注册所有这些实现是使用Simple Injector的单线程:
var container = new Container(); container.RegisterManyForOpenGeneric(typeof(IFooHandler<,>) , Assembly.GetExecutingAssembly()); // resolve: container.GetInstance>();
有许多高级选项,您可以使用它们来大大提高应用程序的“SOLIDness”。 这些都可以在文档中找到。
我想提到一个具体的问题:通过注册一个开放的通用装饰器,Simple Injector能够检索用这个(或更多)装饰器修饰的实例。 此function使得它非常容易坚持SOLID设计,并且仍然可以实现最先进的方案和/或交叉问题。 请注意,即使在这种情况下,Simple Injector也会查看并根据generics类型约束和不同的装饰器进行操作。