# Immutable Messages samples ## Code walk-through This sample shows how to define and exchange immutable messages between endpoints. Immutable messages can be defined as interfaces that contain only getters: ```cs public interface IMyMessage { string Data { get; } } ``` Or as classes with only getters and a non-default parameterless constructor: ```cs public class MyMessage { public MyMessage(string data) { Data = data; } public string Data { get; private set; } } ``` ### Sending messages The sender endpoint can send messages to the receiver using either an immutable message defined as a class or one defined as an interface. In the latter case, the sender endpoint defines an internal message class that implements the public, shared interface: ```cs class MyMessageImpl : IMyMessage { public string Data { get; set; } } ``` The internal class is then used by the sender endpoint at dispatch time: ```cs var myMessage = new MyMessageImpl() { Data = data }; return messageSession.Send(myMessage); ``` > [!NOTE] > The class is compatible with any serializer that has public getters and setters. ### Receiving messages 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 of deserializing objects using private setters and/or non-public parameterless constructors. The receiver endpoint defines regular message handlers: ```cs public class MyMessageAsInterfaceHandler(ILogger logger) : IHandleMessages { public Task Handle(IMyMessage message, IMessageHandlerContext context) { logger.LogInformation("IMyMessage (as interface) received from server with data: {Data}", message.Data); return Task.CompletedTask; } } ``` ```cs public class MyMessageAsClassHandler(ILogger logger) : IHandleMessages { public Task Handle(MyMessage message, IMessageHandlerContext context) { logger.LogInformation("MyMessage (as class) received from server with data: {Data}", message.Data); return Task.CompletedTask; } } ```