Pipeline Management Using Message Mutators
The message pipeline in NServiceBus 2.X pretty much consisted of what we called message modules.
They served their purpose but didn’t quite give you the full control over the message pipeline needed to do more advanced things.
Another major shortcoming was that there was no way to hook into the pipeline at the sending/client side of the message conversation.
When introducing the DataBus feature of NServiceBus 3.0 we came up with the notion of message mutators to solve a specific
requirement to change the content of a message before and after sending it on the wire.
The message mutators turned out to be a nice addition to our pipeline both in terms of their ability to change message content but also to serve as more fine grained hooks into the pipeline.
Lets take a look at how to use them!
NServiveBus 2 Flavors of Mutators
NServiceBus enables 2 types of message mutators:
-
Applicative Messages Mutators
Message mutators is used to change/react to individual messages being send or received.
The
IMessageMutator interface
lets you implement hooks for both the sending side and the receiving side.
If you only need one or the other you can implement one of the more fine grained
IMutateOutgoingMessages or
IMutateIncomingMessages.
Reacting to individual messages can be used to perform things like validation of outgoing/incoming messages.
Have a look at the Message Mutators Sample to see it in action.
NServiceBus uses this type of mutator internally to do things like property encryption and serialization/de serialization of properties to and from the DataBus.
-
Transport Messages Mutators
Transport message mutators, are created by implementing the
IMutateTransportMessages interface.
This type of mutator works on the entire transport message and is useful for things like compression, header manipulation etc.
A full explanation of the syntax used can be found
here.
Remember that message mutators are NOT automatically registered in the container so in order for them to be invoked you need to register them in the container your self.
When should I use a message mutator?
Just like the recommendation for headers, message mutators should only be used for infrastructure purposes.
So as a rule of thumb only consider using message mutators so solve technical requirements.
What happens if a mutator throws an exception?
If a server side (incoming) mutator throws an exception the message will be aborted, rolled back to the queue and retried.
If a client side (outgoing) message mutator throws an exception, the exception will bubble up to the method calling bus.Send or bus.Publish.
This article was written by Andreas Öhlund and the original blog post can be found
here.
|