簡體   English   中英

通用參數工廠 Object 處理程序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM