Publish and Handle an Event

Component: NServiceBus
NuGet Package NServiceBus (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:

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

Via Message Conventions

The following message:

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

can be declared as an event using the following convention:

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.
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.
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
// 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:

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:

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

Samples

Related Articles


Last modified