Publish and Handle an Event

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

Classifying a message as an event

To publish a message it must be classified as an event. There are two ways of achieving this

Via a Marker interface

Adding a marker interface to the message definition.

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

Via Message Conventions

Using the EventWithConvention message convention.

Given a message with the following definition.

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

It could be treated 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");
    });

Handling a event

An event can be handled by use of the IHandleMessages interface on any Handler or Saga.

Publishing an event

In Version 6, the IBus interface has been deprecated and removed. Use the Publish methods on the IMessageHandlerContext interface within a handler, or the IEndpointInstance/IMessageSession interface instead.

An event can be published via any instance of IBus. However there are several common locations where publishing occurs.

From a Handler

From a handler in reaction to some other message being handled.

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

From a handler in reaction to some other message being handled.

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

At startup of an endpoint, directly after the bus has started.

Edit
// Other config
var endpointInstance = await Endpoint.Start(endpointConfiguration)
    .ConfigureAwait(false);
await endpointInstance.Publish(new MyEvent())
    .ConfigureAwait(false);

Events as Classes or Interfaces

Events can be either classes or interfaces. Since interfaces cannot be constructed there are slightly different semantics for publishing each.

Publish a class

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

Publish an interface

If using interfaces to define event contracts set the message properties by passing in a lambda. NServiceBus will then generate a proxy and set those properties.

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

Samples

Related Articles


Last modified