Search code examples
nservicebusnservicebus5nservicebus6

How can I see the destination of an nserviceBus message?


In version 5 of nServiceBus I have a Behavior that keeps track of messages in flight.

In the Behavior I was able to access DeliveryOptions(SendOptions) and see the Destination Queue, in NSB 6 with the change to the Behavior I can't seem to access the destination of the message any more.

Does anyone know of to access the destination of an outgoing message from a Behavior?

Previous code in v5:

 public class PendingCommandBehavior : IBehavior<OutgoingContext>
 {
        public void Invoke(OutgoingContext context, Action next)
        {
            var sendOptions = context.DeliveryOptions as Nsb.Unicast.SendOptions;
            if (sendOptions != null && context.OutgoingMessage.MessageIntent == Nsb.MessageIntentEnum.Send)
            {
                var destinationEndpoint = sendOptions.Destination.Queue;

Code in v6:

 public class PendingCommandBehavior : Behavior<IOutgoingSendContext>
    {
        public override async Task Invoke(IOutgoingSendContext context, Func<Task> next)
        {
            // context doesn't have any destination queue information???

Solution

  • The IOutgoingSendContext is too early in the pipeline to capture the physical destination. Each outgoing send operation will go through the following contexts (in order) in NServiceBus version 6:

    • IOutgoingSendContext
    • IOutgoingLogicalMessageContext
    • IOutgoingPhysicalMessageContext
    • IRoutingContext
    • IBatchDispatchContext (if you are sending from inside a message handler)
    • IDispatchContext

    After IOutgoingSendContext a routing strategy is selected but it is not converted into a physical address until after IRoutingContext.

    For that reason, if you want to track physical addresses, the best bet is to sit in the IDispatchContext. This context will contain a collection of TransportOperations, each of which has an AddressTag. This will either be an instance of UnicastAddressTag with a Destination or an instance of MulticastAddressTag with a MessageType.

    Here is some code to get you started:

    public override Task Invoke(IDispatchContext context, Func<Task> next)
    {
        foreach (var operation in context.Operations)
        {
            if (operation.AddressTag is UnicastAddressTag unicastAddressTag)
            {
                var destinationEndpoint = unicastAddressTag.Destination;
            }
        }
    
        return next();
    }
    

    For more info about the NServiceBus version 6 pipeline, see Steps, Stages and Connectors in the NServiceBus documentation.