NServiceBus: указание порядка сообщений

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

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

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

Обновить

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

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

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

3 ответа

Решение

Как описано в 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>>();
     }
}

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

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

    }
}

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

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

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

Другие вопросы по тегам