【发布时间】:2019-11-12 20:48:29
【问题描述】:
我有一个 API 涉及几个无行为的参数对象,每个对象都有自己的处理程序:
//some POCOs
public class CustomerChange : IChange{
public int CustomerId {get;set;}
public DateTime TimeStamp {get;set;}
}
public class SomeOtherChange : IChange{
public int AParameter {get;set;}
public string AnotherParameter {get;set;}
public DateTime TimeStamp {get;set;}
}
// stateless handlers that will be resolve with a DI container (Ninject in my case)
public interface IChangeHandler<TChange>{
public Handle(T change);
}
public class CustomerChangeHandler : IChangeHandler<CustomerChange>{
private readonly ICustomerRepository customerRepository;
public CustomerChangeHandler(ICustomerRepository repo){
customerRepository = repo;
}
public Handle(CustomerChange change){
customerRepository.DoStuff(change.CustomerId);
}
}
等等。
当 IChange 的类型在编译时已知时,这很有效,但是,我遇到了需要处理未知类型的 IChange 的情况。
在一个理想的世界里,我希望能够做这样的事情:
public class ChangeHandlerFactory {
public void HandleChange(IChange change){
// get the change handler from the DI container based on the concrete type of IChange
var handlerType = typeof(IChangeHandler<>)
.MakeGenericType(change.GetType());
object handler = container.GetInstance(handlerType); //is this an acceptable way to use a DI container? I would need a dependency on IKernel in this case
handler.Handle(change); // I would need to cast the change object to the appropriate type for the handler or make handler dynamic which seems like it has the potential for hard to debug issues
}
}
我对将处理程序作为动态处理程序的担忧是,有人可能会做一些不正确的事情并导致难以调试的错误。
我可以让每个 POCO 实现一个 GetHandler 方法来检索处理程序,但这几乎破坏了首先将它们分开的全部意义。
在这种情况下让处理程序的最佳方法是什么?有没有办法在不使用我的 DI 容器(ninject)作为服务定位器和/或不使用动态的情况下做到这一点?我发现我已经多次遇到这种情况,但还没有想出一个感觉正确的解决方案。
【问题讨论】:
-
当 IChange 的类型在运行时已知时,这很有效,但是,我遇到了需要在运行时处理未知类型的 IChanges 的情况你的意思是编译时间?如果你在运行时不能分辨出什么是什么类型,那么就会发生一些真正的错误:D
标签: c# dependency-injection polymorphism factory factory-pattern