[英]Factory For Generic Parameter Object Handler
我有一個 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)作為服務定位器和/或不使用動態的情況下做到這一點? 我發現我已經多次遇到這種情況,但還沒有想出一個感覺正確的解決方案。
最簡單的是依賴倒置。 讓 POCO 提供一個委托來獲取它自己的處理程序,因為它顯然已經知道它是什么類型。
interface IChange
{
IChangeHandler GetHandler(Container container);
}
public class SomeOtherChange : IChange
{
public int AParameter {get;set;}
public string AnotherParameter {get;set;}
public DateTime TimeStamp {get;set;}
public IChangeHandler GetHandler(Container container) => container.GetInstance<SomeOtherChangeHandler>();
}
然后你可以編寫一個通用的處理程序映射器:
public void HandleChange(IChange change)
{
var handler = change.GetHandler(container);
//etc....
當然,這給你留下了一個問題,即一旦你擁有了處理程序,如何處理它。 同樣,您可以讓 POCO 完成工作:
public class SomeOtherChange : IChange
{
public int AParameter {get;set;}
public string AnotherParameter {get;set;}
public DateTime TimeStamp {get;set;}
public void GetAndCallHandler(Container container)
{
var handler = container.GetInstance<SomeOtherChangeHandler>();
handler.Handle(this);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.