【问题标题】:Factory For Generic Parameter Object Handler通用参数对象处理程序的工厂
【发布时间】: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


【解决方案1】:

最简单的是依赖倒置。让 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);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    相关资源
    最近更新 更多