Immutable Messages samples

Component: NServiceBus
NuGet Package NServiceBus (7.x)

Code walk-through

This sample shows how to define and exchange immutable messages between endpoints. Immutable messages can be defined as interfaces with only getters:

public interface IMyMessage
{
    string Data { get; }
}

Or as classes with only getters and a non-default parameterless constructor:

public class MyMessage
{
    public MyMessage(string data)
    {
        Data = data;
    }

    public string Data { get; private set; }
}

At startup the application creates two endpoint instances, a sender and a receiver. Both are configured to use Json.Net as serializer through the NServiceBus.Newtonsoft.Json package:

var endpointConfiguration = new EndpointConfiguration("Samples.ImmutableMessages.UsingInterfaces.Sender");
endpointConfiguration.UseSerialization<NewtonsoftSerializer>();
endpointConfiguration.UsePersistence<LearningPersistence>();
var transportConfiguration = endpointConfiguration.UseTransport<LearningTransport>();

Sending messages

The sender endpoint allows to send messages to the receiver using either an immutable message defined as a class or one defined as an interface. In this latter case the sender endpoint defines an internal message class that implements the public, shared, interface:

class MyMessageImpl : IMyMessage
{
    public string Data { get; set; }
}

The internal class is then used by the sender endpoint at dispatch time

var myMessage = new Messages.MyMessageImpl()
{
    Data = data
};
return endpointInstance.Send(myMessage);
The class is compatible with any serializer if it has public getters and setters

Receiving message

To receive an immutable message defined using one of the two presented techniques no special configuration is needed. The only requirement is a serializer capable, or configurable to do so, of deserializing objects using private setters and/or non-public parameterless constructors. The receiver endpoint defines regular message handlers:

public class MyMessageAsInterfaceHandler :
    IHandleMessages<IMyMessage>
{
    static ILog log = LogManager.GetLogger<MyMessageAsInterfaceHandler>();

    public Task Handle(IMyMessage message, IMessageHandlerContext context)
    {
        log.Info($"IMyMessage (as interface) received from server with data: {message.Data}");
        return Task.CompletedTask;
    }
}
public class MyMessageAsClassHandler :
    IHandleMessages<MyMessage>
{
    static ILog log = LogManager.GetLogger<MyMessageAsClassHandler>();

    public Task Handle(MyMessage message, IMessageHandlerContext context)
    {
        log.Info($"MyMessage (as class) received from server with data: {message.Data}");
        return Task.CompletedTask;
    }
}

Related Articles


Last modified