Getting Started
Architecture
NServiceBus
Transports
Persistence
Hosting
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Modernization
Samples

Callback Usage

Component: Callbacks
NuGet Package: NServiceBus.Callbacks 6.x
Target Version: NServiceBus 10.x

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.
  2. 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.

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

var message = new EnumMessage();
var sendOptions = new SendOptions();
sendOptions.SetDestination("Samples.Callbacks.Receiver");
var status = await messageSession.Request<Status>(message, sendOptions);
Console.WriteLine($"Callback received with status:{status}");

Send and callback for an int

var message = new IntMessage();
var sendOptions = new SendOptions();
sendOptions.SetDestination("Samples.Callbacks.Receiver");
var response = await messageSession.Request<int>(message, sendOptions);
Console.WriteLine($"Callback received with response:{response}");

Send and callback for an object

var message = new ObjectMessage();
var sendOptions = new SendOptions();
sendOptions.SetDestination("Samples.Callbacks.Receiver");
var response = await messageSession.Request<ObjectResponseMessage>(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

public class EnumMessageHandler(ILogger<EnumMessageHandler> logger) :
    IHandleMessages<EnumMessage>
{
    public Task Handle(EnumMessage message, IMessageHandlerContext context)
    {
        logger.LogInformation("Message received, Returning");
        return context.Reply(Status.OK);
    }
}

Return an int

public class IntMessageHandler(ILogger<IntMessageHandler> logger) :
    IHandleMessages<IntMessage>
{
    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.

public class ObjectMessageHandler(ILogger<ObjectMessageHandler> logger) :
    IHandleMessages<ObjectMessage>
{
    public Task Handle(ObjectMessage message, IMessageHandlerContext context)
    {
        logger.LogInformation("Message received, Returning");
        var objectResponseMessage = new ObjectResponseMessage
        {
            Property = "PropertyValue"
        };
        return context.Reply(objectResponseMessage);
    }
}