【问题标题】:How to resolve handler in a clean way如何以干净的方式解决处理程序
【发布时间】:2019-10-08 20:36:45
【问题描述】:

我试图找到一种简单的方法来解决我的处理程序。解决方案是“处理不同类型的消息”。但是我找到的每个解决方案,例如this idea,我都坚持解析处理程序,因为我的处理程序有一个构造函数,它对其他接口有一些依赖关系。

例如,如果我遵循上述想法,我的OrderMessageHandler

public class OrderMessageHandler
{
    private readonly IInterface _interface;
    public OrderMessageHandler(IInterface interface) {_inteface=interface}

    bool HandleMessage( IMessage msg ) {
        if ( !(msg is OrderMessage)) return false;
        return true; 
    }
}

但是 IInterface 有其他依赖项,我不能简单地解决这个问题。 我想知道是否有人比下面的课程有更好的主意?

public class MessageProcessor {
    private List<IMessageHandler> handlers;

    public MessageProcessor() {
       handlers = new List<IMessageHandler>();
       handlers.add(new SomeOtherMessageHandler());
       handlers.add(new OrderMessageHandler());
    }

    public void ProcessMessage( IMessage msg ) {
       bool messageWasHandled
       foreach( IMessageHandler handler in handlers ) {
           if ( handler.HandleMessage(msg) ) {
               messageWasHandled = true;
               break;
           }
       }

       if ( !messageWasHandled ) {
          // Do some default processing, throw error, whatever.
       }
    }
}

【问题讨论】:

  • 您是否尝试过使您的IMessageHandler 接口通用,例如IMessageHandler&lt;TMessage&gt;?这是一种非常常见的方法,将摆脱您当前正在进行的所有类型检查。
  • @Steven 我做到了。我的主要问题是这条消息处理器以干净简单的方式找到正确的处理程序。我解决了它,但它似乎非常复杂且缺乏可读性。我使用了 Activator.CreateInstance 甚至调用。我对那些不满意

标签: c# dependency-injection dependency-resolver


【解决方案1】:

按照Explicit Dependencies Principle,可以确保所有必要的依赖都注入到哪里。

public class MessageProcessor {
    private List<IMessageHandler> handlers;

    public MessageProcessor(IEnumerable<IMessageHandler> handlers) {
        this.handlers = new List<IMessageHandler>(handlers);
        //removed
        //handlers.add(new SomeOtherMessageHandler()); 
        //handlers.add(new OrderMessageHandler());
    }

    public void ProcessMessage( IMessage msg ) {
       bool messageWasHandled
       foreach( IMessageHandler handler in handlers ) {
           if ( handler.HandleMessage(msg) ) {
               messageWasHandled = true;
               break;
           }
       }

       if ( !messageWasHandled ) {
          // Do some default processing, throw error, whatever.
       }
    }
}

如果使用 DI 容器,请确保注册所有相关方

伪代码:

container.Register<IInterface, Implementation>();
container.Register<IMessageHandler, SomeOtherMessageHandler>();
container.Register<IMessageHandler, OrderMessageHandler>();
container.Register<MessageProcessor>();

这样容器在解析所需类型时知道如何构建对象图

MessageProcessor processor = container.Resolve<MessageProcessor>();

processor.ProcessMessage(...);

//...

如果使用Pure DI,这仍然允许在需要的地方正确创建和注入所有涉及的类型。

IInterface dependency = new Implementation();
List<IMessageHandler> handlers = new List<IMessageHandler>();
handlers.Add(new SomeOtherMessageHandler()); 
handlers.Add(new OrderMessageHandler(dependency));
MessageProcessor processor = new MessageProcessor(handlers);

processor.ProcessMessage(...);

//...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 2021-03-20
    • 1970-01-01
    • 2016-11-26
    相关资源
    最近更新 更多