Producer Behaviors Pipeline
Each message produced by Silverback is processed by a pipeline of behaviors enabling different features and customizations. The SortIndex property of each behavior determines the order in which they are executed and each behavior passes the message along the pipeline to the next behavior.
Default Behaviors
The following table lists the default behaviors that are executed when producing a message.
| Name | Index | Description |
|---|---|---|
| ActivityProducerBehavior | 100 | Starts an Activity and adds the tracing information to the message headers. |
| HeadersWriterProducerBehavior | 200 | Maps the properties decorated with the HeaderAttribute to the message headers. |
| MessageEnricherProducerBehavior | 250 | Invokes all the IOutboundMessageEnricher configured for the endpoint. |
| KafkaMessageKeyInitializerProducerBehavior | 300 | Sets the Kafka key with the value from the properties decorated with the KafkaKeyMemberAttribute, unless a key is already set. |
| FilterProducerBehavior | 400 | Applies the configured filters to the message being produced. |
| BinaryMessageHandlerProducerBehavior | 500 | Switches to the BinaryMessageSerializer if the message being produced implements the IBinaryMessage interface. |
| ValidatorProducerBehavior | 550 | Validates the message being produced. |
| SerializerProducerBehavior | 600 | Serializes the message being produced using the configured IMessageSerializer. |
| EncryptorProducerBehavior | 700 | Encrypts the message when encryption is enabled. |
| SequencerProducerBehavior | 800 | Uses the available implementations of ISequenceWriter (e.g. ChunkSequenceWriter) to set the proper headers and split the published message or messages set to create the sequences. |
| CustomHeadersMapperProducerBehavior | 1000 | Applies the custom header name mappings. |
Custom Behaviors
It is possible to add custom behaviors to the pipeline to implement cross-cutting concerns, and add new features to Silverback.
A behavior is a class implementing the IProducerBehavior interface. The HandleAsync method is called for each message being produced, allowing the behavior to modify the message or perform additional operations.
The following basic example demonstrates how to set a custom message header on each outbound message.
public class CustomHeadersProducerBehavior : IProducerBehavior
{
public int SortIndex => 1000;
public async ValueTask HandleAsync(
ProducerPipelineContext context,
ProducerBehaviorHandler next,
CancellationToken cancellationToken)
{
context.Envelope.Headers.Add("generated-by", "silverback");
await next(context, cancellationToken);
}
}
The custom behavior must be registered at startup using the AddSingletonBrokerBehavior, or AddTransientBrokerBehavior method. The transient behavior will be resolved once per producer, while the singleton behavior will be shared.
services
.AddSilverback()
...
.AddSingletonBrokerBehavior<CustomHeadersProducerBehavior>();
Additional services can be injected into the behavior constructor, or resolved via the ServiceProvider from the ProducerPipelineContext if a scoped instance is required.