NServiceBus: указание порядка сообщений - PullRequest
4 голосов
/ 04 ноября 2010

Я использую NServiceBus в своем собственном процессе (поэтому не с использованием общего хоста), и я хотел бы иметь несколько обработчиков сообщений для сообщения в определенном порядке.Для Generic Host вы бы реализовали ISpecifyMessageHandlerOrdering, но я не знаю, как это сделать при размещении вашего собственного процесса NServiceBus, так как этот интерфейс определен в NServiceBus.Host.exe, и я не смог найти другой способ сделатьэтот.

Целью этого является аутентификация пользователя: перед вызовом фактического обработчика сообщений я сначала хотел бы аутентифицировать отправителя сообщения, что произошло бы в другом, более общем, обработчике сообщений.Сообщение будет иметь тип, который содержит зашифрованное имя пользователя и пароль и / или идентификатор сеанса.Этот тип будет использоваться почти для всех команд, отправляемых на сервер (я думаю, все, кроме входа в систему).Это нормальный способ аутентификации пользователя с использованием NServiceBus?

В настоящее время он выбирает второй обработчик, но не в правильном порядке.

Обновление

По предложению Дэвида я попытался создать IMessageModule и чтение заголовков из CurrentMessageContext для аутентификации пользователя.

Я столкнулся с некоторыми проблемами здесь:

  • Когда я отправляю сообщение в первый раз, bus.CurrentMessageContextnull.Каждый раз после этого он заполняется правильно, и я могу читать заголовки.
  • Вызов bus.DoNotContinueDispatchingCurrentMessageToHandlers, когда пользователь не аутентифицирован, не останавливает вызов обработчиков сообщений.Также не bus.Return(errorCode).Есть ли другие способы, которыми я могу сделать это?

Ответы [ 3 ]

7 голосов
/ 04 ноября 2010

Как описано в FAQ для NServiceBus на странице документации:

http://docs.particular.net/nservicebus/handlers/handler-ordering

Как указать порядок вызова обработчиков?

Если вы пишете свой собственный хост:

NServiceBus.Configure.With()
 ...
 .UnicastBus()
      .LoadMessageHandlers(First<H1>.Then<H2>().AndThen<H3>().AndThen<H4>() //etc)
 ...

Если вы используете общий хост

public class EndpointConfig : IConfigureThisEndpoint, ISpecifyMessageHandlerOrdering
{
     public void SpecifyOrder(Order order)
     {
          order.Specify(First<H1>.Then<H2>().AndThen<H3>().AndThen<H4>() //etc);
     }
}

Если вы хотите указать только один обработчик (с вашим собственным хостом)

NServiceBus.Configure.With()
     ...
     .UnicastBus()
          .LoadMessageHandlers<FIRST<YourHandler>>()
     ...

Если вы хотите указать только один обработчик (с общим хостом)

public class EndpointConfig : IConfigureThisEndpoint, ISpecifyMessageHandlerOrdering
{
     public void SpecifyOrder(Order order)
     {
          order.Specify<FIRST<YourHandler>>();
     }
}
4 голосов
/ 04 ноября 2010

Другой возможностью будет реализация базового класса обработчика сообщений, который будет условно пропускать обработку на основе вашей проверки подлинности.

public abstract class MessageHandlerBase<T> : IMessageHandler<T> where T : IMessage
{
    public abstract void HandleMessage(T message);

    public void Handle(T message)
    {

        if (CredentialsValid(message))
            this.HandleMessage(message);

    }
}
3 голосов
/ 04 ноября 2010

Рассматривали ли вы модуль сообщений для этой цели?

public interface IMessageModule
{
    // Methods
    void HandleBeginMessage();
    void HandleEndMessage();
    void HandleError();
}

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

...