# Callback Usage > [!WARNING] > Callbacks should only be used in exceptional situations, for example, to introduce messaging behind a synchronous API in a legacy component that can't be changed. They allow gradually transitioning applications towards messaging. See the [when to use callbacks](/nservicebus/messaging/callbacks.md#when-to-use-callbacks) section for more information. Callbacks allow a sender to receive a response value directly from a message handler, turning a one-way send into a request/reply interaction. This sample demonstrates callbacks returning an enum, an integer, and an object. ## Running the sample 1. Run the solution. Two console applications will start. 1. In the Sender console application, press various keys to trigger each scenario when prompted. ## Shared project A class library containing the messages and shared code. ### Status enum This is used for the enum callback scenario. ```csharp public enum Status { OK, Error } ``` ## Sender project A console application responsible for sending messages and handling the callback from the reply. ### Send and callback for an enum ```cs var message = new EnumMessage(); var sendOptions = new SendOptions(); sendOptions.SetDestination("Samples.Callbacks.Receiver"); var status = await endpointInstance.Request(message, sendOptions); Console.WriteLine($"Callback received with status:{status}"); ``` ### Send and callback for an int ```cs var message = new IntMessage(); var sendOptions = new SendOptions(); sendOptions.SetDestination("Samples.Callbacks.Receiver"); var response = await endpointInstance.Request(message, sendOptions); Console.WriteLine($"Callback received with response:{response}"); ``` ### Send and callback for an object ```cs var message = new ObjectMessage(); var sendOptions = new SendOptions(); sendOptions.SetDestination("Samples.Callbacks.Receiver"); var response = await endpointInstance.Request(message, sendOptions); Console.WriteLine($"Callback received with response property value:{response.Property}"); ``` ## Receiver project A console application responsible for replying to messages from the Sender. ### Return an enum ```cs public class EnumMessageHandler : IHandleMessages { private readonly ILogger logger; public EnumMessageHandler(ILogger logger) { this.logger = logger; } public Task Handle(EnumMessage message, IMessageHandlerContext context) { logger.LogInformation("Message received, Returning"); return context.Reply(Status.OK); } } ``` ### Return an int ```cs public class IntMessageHandler : IHandleMessages { private readonly ILogger logger; public IntMessageHandler(ILogger logger) { this.logger = logger; } public Task Handle(IntMessage message, IMessageHandlerContext context) { logger.LogInformation("Message received, Returning"); return context.Reply(10); } } ``` ### Return an object Note that this scenario requires a `Reply` with a real message. ```cs public class ObjectMessageHandler : IHandleMessages { private readonly ILogger logger; public ObjectMessageHandler(ILogger logger) { this.logger = logger; } public Task Handle(ObjectMessage message, IMessageHandlerContext context) { logger.LogInformation("Message received, Returning"); var objectResponseMessage = new ObjectResponseMessage { Property = "PropertyValue" }; return context.Reply(objectResponseMessage); } } ```