Aren’t martens really cute?
By the way, JasperFx Software is up and running for formal support plans for both Marten and Wolverine!
Wolverine 1.11.0 was released this week (here’s the release notes) with a small improvement to its ability to subscribe to Marten events captured within Wolverine message handlers or HTTP endpoints. Since Wolverine 1.0, users have been able to opt into having Marten forward events captured within Wolverine handlers to any known Wolverine subscribers for that event with the EventForwardingToWolverine() option.
The latest Wolverine release adds the ability to automatically publish an event as a different message using the event data and its metadata as shown in the sample code below:
builder.Services.AddMarten(opts =>
{
var connectionString = builder.Configuration.GetConnectionString("marten");
opts.Connection(connectionString);
})
// Adds Wolverine transactional middleware for Marten
// and the Wolverine transactional outbox support as well
.IntegrateWithWolverine()
.EventForwardingToWolverine(opts =>
{
// Setting up a little transformation of an event with its event metadata to an internal command message
opts.SubscribeToEvent<IncidentCategorised>().TransformedTo(e => new TryAssignPriority
{
IncidentId = e.StreamId,
UserId = e.Data.UserId
});
});
This isn’t a general purpose outbox, but rather immediately publishes captured events based on normal Wolverine publishing rules immediately at the time the Marten transaction is committed.
So in this sample handler:
public static class CategoriseIncidentHandler
{
public static readonly Guid SystemId = Guid.NewGuid();
// This Wolverine handler appends an IncidentCategorised event to an event stream
// for the related IncidentDetails aggregate referred to by the CategoriseIncident.IncidentId
// value from the command
[AggregateHandler]
public static IEnumerable<object> Handle(CategoriseIncident command, IncidentDetails existing)
{
if (existing.Category != command.Category)
{
// Wolverine will transform this event to a TryAssignPriority message
// on the successful commit of the transaction wrapping this handler call
yield return new IncidentCategorised
{
Category = command.Category,
UserId = SystemId
};
}
}
}
To try to close the loop, when Wolverine handles the CategoriseIncident
message, it will:
- Potentially append an
IncidentCategorised
event to the referenced event stream - Try to transform that event to a new
TryAssignPriority
message - Commit the changes queued up to the underlying Marten
IDocumentSession
unit of work - If the transaction is successful, publish the
TryAssignPriority
message — which in this sample case would be routed to a local queue within the Wolverine application and handled in a different thread later
That’s a lot of text and gibberish, but all I’m trying to say is that you can make Wolverine reliably react to events captured in the Marten event store.