Uses a file share to store attachments for messages.
Two settings are required as part of the default usage:
- A file share or directory location.
- A default time to keep for attachments.
NServiceBus. method for attachment cleanup.
This usage results in the following:
Attachment cleanup is enabled by default. It can be disabled using the following:
When the cleanup task runs it uses the
Expiry column to determine if a given attachment should be deleted. This column is populated when an attachment is written. When adding an attachment to an outgoing message, all methods accept an optional parameter
timeToKeep of the type
GetTimeToKeep is defined as:
public delegate TimeSpan GetTimeToKeep(TimeSpan? messageTimeToBeReceived);
messageTimeToBeReceived is value of TimeToBeReceived. If no
timeToKeep parameter for a specific attachment is defined then the endpoint level
timeToKeep is used.
The result of
timeToKeep is then added to the current date and persisted to the
TimeToKeep. provides a recommended default for for attachment lifetime calculation:
- If TimeToBeReceived is defined then keep attachment for twice that time.
- Else; keep for 10 days.
Approaches to using attachments for an outgoing message.
While the below examples illustrate adding an attachment to
SendOptions, equivalent operations can be performed on
The recommended approach for adding an attachment is by providing a delegate that constructs the stream. The execution of this delegate is then deferred until later in the outgoing pipeline, when the instance of the stream is required to be persisted.
There are both async and sync variants.
In some cases an instance of a stream is already available in scope and as such it can be passed directly.
Approaches to using attachments for the current incoming message.
Processes an attachment with a specific name.
Processes all attachments.
Copy an attachment with a specific name to another stream.
Get a stream for an attachment with a specific name.
Get a byte array for an attachment with a specific name.
All of the above examples have companion methods that are suffixed with
ForMessage. These methods allow a handler or saga to read any attachments as long as the message id for that attachment is known. For example processing all attachments for a specific message could be done as follows
This can be helpful in a saga that is operating in a Scatter-Gather mode. So instead of storing all binaries inside the saga persister, the saga can instead store the message ids and then, at a latter point in time, access those attachments.
The below examples also use the NServiceBus.Testing extension.
To mock or verify incoming attachments is it necessary to inject a instance of
IMessageAttachments into the current
IMessageHandlerContext. This can be done using the
MockAttachmentHelper. extension method which exists in the
The implementation of
IMessageHandlerContext can be a custom coded mock or constructed using any of the popular mocking/assertion frameworks.
There is a default implementation of
MockMessageAttachments. This implementation stubs out all methods. All members are virtual so it can be used as simplified base class for custom mocks.
Putting these parts together allows a handler, using incoming attachments, to be tested.