【发布时间】:2023-03-31 08:03:01
【问题描述】:
我有如下界面...
public interface IHandler<in TFor> where TFor : IRequest
{
void Handle(IEnumerable<TFor> requests);
}
通常是这样实现的...
public class AssignmentHandler : HandlerBase, IHandler<AssignmentRequest>
{
public void Handle(IEnumerable<AssignmentRequest> assigmentRequests)
{
foreach(var request in assignmentRequests).....
}
}
IRequest 只是一个标记接口(此时)。
我通过以下约定注册所有处理程序...
public override void Load()
{
Kernel.Bind(x => x.FromAssemblyContaining<IHandler>()
.SelectAllClasses()
.InheritedFrom(typeof(IHandler<>))
.BindAllInterfaces());
//i also tried...
Kernel.Bind(x => x.FromAssemblyContaining<IHandler>()
.SelectAllClasses()
.InheritedFrom<IHandler<IRequest>>()
.BindSingleInterface());
}
他们单独解决就好了。
在一种情况下,我想解析所有处理程序,并将它们注入到这样的构造函数中......
public SomeConstructor(IEnumerable<IHandler<IRequest>> allHandlers)
这不起作用,总是返回空。
我的理解是因为我按照惯例将它们注册为IHandler<ConcreteRequest>,而不是IHandler<IRequest>,这是两个不同的签名。
我如何按照惯例注册所有处理程序,以将它们共同标识为IEnumerable<IHandler<IRequest>>,同时也单独标识?
第二次注册是可以的,但更希望通过两个签名解决一个实现。
【问题讨论】:
-
无法将处理程序
FooHandler : IHandler<FooRequest>强制转换为IHandler<IRequest>。使用任何 IoC 都无法实现这一点,因为TRequest类型参数不能同时为in和out.. -
可以直接使用
IRequest接口,为什么还要使用TFor泛型? -
因为每个请求类型都有自己的处理程序类型。
标签: c# ninject open-generics