Как решить обработчик в чистом виде - PullRequest
1 голос
/ 08 октября 2019

Я пытаюсь найти простой способ разрешить свои обработчики. Решение - «обработка разных типов сообщений». но каждое найденное мной решение, такое как , эта идея , я застревал в разрешении обработчика, потому что у моего обработчика есть конструктор, который имеет некоторые зависимости от других интерфейсов.

Например, если я буду следовать упомянутой идее, мой 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.
       }
    }
}

1 Ответ

2 голосов
/ 08 октября 2019

Следуя Явному принципу зависимостей , вы можете убедиться, что все необходимые зависимости введены куда.

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(...);

//...

При использовании PureDI это все еще позволяет правильно создавать и вводить все вовлеченные типы при необходимости.

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(...);

//...
...