我发现了许多与我面临的问题类似的问题和回答;但我无法拼凑出一个可行的解决方案。
我有以下内容:
public interface IProcessing<V,W> where W: TaskResponse where V: TaskRequest
{
W process(V req);
}
TaskRequest
&是TaskResponse
抽象基类
这个具体的类也被定义:
public class MathProcessor : IProcessing<MathRequest, MathResponse>
{
public MathResponse process(MathRequest req) {
// do stuff
// create a MathResponse instance
return resp;
}
}
其中MathRequest
&MathResponse
是派生类,各个抽象类用作接口定义中的约束。
根据其接口注册具体类型并使用 autofac 解析是可以的。
但是,在运行时尝试基于另一种类型(在本例中为请求对象,例如 )解析具体类型的预期用途出现了困难MathRequest
。这基本上是为了实现常见的消息处理程序模式(以下是伪代码),其中接收消息并将其分派到适当的处理程序:
TaskRequest req = getNextRequest();
var proc = container.Resolve(req.getType().Name)
proc.process(req);
根据论坛中的相关主题,基本建议是定义一个工厂并将其注册到容器中,然后在运行时使用该工厂根据提供的参数创建我需要的对象。这似乎是对的。
我还看到了使用IIndex<K,V>
autofac 中的功能按键查找适当类型/服务的相关建议。
我在注册和MathProcessor
通过键解析类型时遇到问题,其中键是一种类型(在这种情况下MathRequest
)。该错误可能与通用接口定义和允许的内容更相关。
注册:
builder.RegisterType<MathProcessor>().As<IProcessing<MathRequest, MathResponse>>().Keyed<IProcessing<MathRequest, MathResponse>>(strTypeName);
可以,但是
builder.RegisterType<MathProcessor>().As<IProcessing<TaskRequest, TaskResponse >>().Keyed<IProcessing< TaskRequest, TaskResponse >>(strTypeName);
不是。
注意:基于.Net中关于泛型类型和协变的所有帖子,我将接口更改为:
public interface IProcessing<in V, out W> where W: TaskResponse where V: TaskRequest
{
W process(V req);
}
但这只是猜测,没有很好的理解。在我天真的观点 MathProcessor 是 IProcessing 的一种,但似乎并非如此。