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, вы можете получить доступ к текущему контексту сообщения и оттуда проверить заголовки и использовать его для аутентификации ваших сообщений.