Publish and Handle an Event

Component: NServiceBus | Nuget: NServiceBus (Version: 6.x)

Defining events

The messages need to be declared as an event before they can be published. That can be done with marker interfaces or using message conventions.

Via a Marker interface

Add IEvent marker interface to the message definition:

Edit
namespace Domain.Messages
{
    public class UserCreatedEvent :
        IEvent
    {
        public string Name { get; set; }
    }
}

Via Message Conventions

The following message:

Edit
namespace Domain.Messages
{
    public class UserCreatedEvent
    {
        public string Name { get; set; }
    }
}

can be declared as an event using the following convention:

Edit
var conventions = endpointConfiguration.Conventions();
conventions.DefiningEventsAs(
    type =>
    {
        return type.Namespace != null &&
               type.Namespace.StartsWith("Domain") &&
               type.Name.EndsWith("Event");
    });

Learn more about conventions and unobtrusive mode.

Handling an event

In order to handle an event, implement IHandleMessages<T> interface in any Handler or Saga class, where T is the specific event type.

Publishing an event

In order to publish an event call the Publish method.

There are a few common scenarios for publishing events. Events might be published:

  • from a handler, when processing another message.
Edit
public class CreateUserHandler :
    IHandleMessages<CreateUserCommand>
{
    public Task Handle(CreateUserCommand message, IMessageHandlerContext context)
    {
        var userCreatedEvent = new UserCreatedEvent
        {
            Name = message.Name
        };
        return context.Publish(userCreatedEvent);
    }
}
  • from a saga handler, when processing another message.
Edit
public class CreateUserSaga :
    Saga<CreateUserSaga.SagaData>,
    IHandleMessages<CreateUserCommand>
{
    public Task Handle(CreateUserCommand message, IMessageHandlerContext context)
    {
        var userCreatedEvent = new UserCreatedEvent
        {
            Name = message.Name
        };
        return context.Publish(userCreatedEvent);
    }
  • at endpoint startup
Edit
// Other config
var endpointInstance = await Endpoint.Start(endpointConfiguration)
    .ConfigureAwait(false);
await endpointInstance.Publish(new MyEvent())
    .ConfigureAwait(false);

Events as Classes or Interfaces

NServiceBus messages can be implemented either as classes or interfaces. Since interfaces cannot be instantiated directly, use the following API to publish events implemented as interfaces:

Edit
return context.Publish<IMyEvent>(
    messageConstructor: message =>
    {
        message.SomeProperty = "Hello world";
    });

When the event message is declared as an interface, NServiceBus will generate a proxy, set properties and publish the message. It's equivalent to the following call:

Edit
var message = new MyEvent
{
    SomeProperty = "Hello world"
};
await context.Publish(message)
    .ConfigureAwait(false);

Samples

Related Articles


Last modified