Wolverine Documentation
repository·main·Indexed 25 days ago
https://github.com/jasperfx/wolverineWolverine is a high-performance .NET Mediator and Message Bus designed for asynchronous messaging and command handling. It features integration with Marten, automated conjoined multi-tenancy for EF Core, and support for both code-first and proto-first gRPC services. The library provides built-in capabilities for mapping .NET exceptions to gRPC StatusCodes via AIP-193 and surfacing rich gRPC error details.
What's inside Wolverine
- Wolverine is a Next Generation .NET Mediator and Message Bus. It is designed for highly productive and performant server-side development in .NET and is often used as part of the 'critter stack' alongside Marten.
Core features of Wolverine.EntityFrameworkCore integration
mainThe
Wolverine.EntityFrameworkCoreproject provides several key capabilities for integrating EF Core with Wolverine:- Transactional Outbox: Atomic database changes and message publishing.
- Saga Persistence: Full CRUD support (load, insert, update, delete) for Sagas via EF Core.
- Multi-tenancy: Support for per-tenant
DbContextcreation using either connection strings orDbDataSource. - Domain Event Publishing: Automatically scrapes and publishes domain events by inspecting entities within the EF Core
ChangeTracker. - Idempotency: Uses inbox tracking to ensure messages are processed exactly once.
- Code Generation: Uses specialized frames that compile into Wolverine's JIT-generated handler pipelines for high performance.
Integrate FluentValidation and Data Annotations
mainWolverine supports advanced validation through integration with standard .NET libraries:
- FluentValidation: Use the full feature set of FluentValidation (rule builders, conditional rules, etc.) by following the integration guide.
- Data Annotations: Use standard .NET attributes like
[Required],[Range], and others directly on your message types.
RabbitMQ Transport Compatibility and Health
mainCompatibility
The
WolverineFX.RabbitMQtransport is verified to work with LavinMQ with 100% protocol compatibility.Health Monitoring
The RabbitMQ transport implements
IBrokerHealthProbe. This allows monitoring tools (like CritterWatch) to perform non-destructive, point-in-time checks on the broker connection, including monitoring reconnect counts and TLS certificate expiry.Key features of the Wolverine Kafka Transport
mainThe Wolverine Kafka transport provides several advanced capabilities for .NET developers:
- Commit Strategies: Idiomatic non-blocking commits with four selectable strategies and in-flight-safe watermarks.
- Scale-out: Native scale-out support using cooperative-sticky rebalancing and static membership.
- Concurrency: Second-tier concurrency by message key within a single partition.
- Consumption Modes: First-class support for cold-start and ephemeral hot-tail consumption.
- Replay: Bounded replay through the standard handler pipeline without affecting the live consumer group.
- Retries: Non-blocking tiered retry topics integrated with the standard error DSL.
- Exactly-once (EOS) building blocks: Support for idempotent producers,
read_committedisolation, and an EOS story built on the durable inbox/outbox pattern.
Note: The transactional read-process-write EOS engine and live seek of a running group-subscribed listener are currently not supported.
Ways to implement validation in Wolverine.HTTP
mainWolverine.HTTP provides three primary ways to implement validation:
- Explicit
Validate()orValidateAsync()methods: The recommended approach for complex logic (e.g., database lookups or IoC service usage). These methods returnProblemDetailsorWolverineContinue.NoProblems. - Fluent Validation middleware: Available via the separate
WolverineFx.Http.FluentValidationNuGet package. - Data Annotations: Can be used by explicitly configuring Data Annotations middleware within your Wolverine.HTTP application setup.
- Explicit
Use Amazon SNS as a messaging transport
mainWolverine supports Amazon SNS via the
WolverineFx.AmazonSnspackage.Important Limitations:
- No Request/Reply: Wolverine cannot support request/reply mechanics (
IMessageBus.InvokeAsync<T>()) with SNS. - Publish-Only: Due to the nature of SNS, Wolverine does not include listening functionality for this transport. To receive messages, you should forward SNS messages to an Amazon SQS queue and use the SQS transport to listen for them.
- No Request/Reply: Wolverine cannot support request/reply mechanics (
Wolverine Performance Metrics Overview
mainWolverine automatically tracks performance metrics using
System.Diagnostics.Metrics, making them compatible with OpenTelemetry-compliant observability tools like Honeycomb or Datadog.Available Metrics
Metric Name Type Description wolverine-messages-sentCounter Number of messages sent wolverine-execution-timeHistogram Execution time in milliseconds wolverine-messages-succeededCounter Number of messages successfully processed wolverine-dead-letter-queueCounter Number of messages moved to dead letter queues wolverine-effective-timeHistogram Time between message being sent and completely handled (ms) wolverine-execution-failureCounter Number of message execution failures (tagged by exception.type)wolverine-inbox-countObservable Gauge Current number of persisted incoming messages (tagged by sourceanddatabase)wolverine-outbox-countObservable Gauge Current number of persisted outgoing messages (tagged by sourceanddatabase)wolverine-scheduled-countObservable Gauge Current number of persisted scheduled messages (tagged by sourceanddatabase)WARNING Metrics for inbox, outbox, and scheduled message counts were lost during the introduction of multi-tenancy and are scheduled to be restored in version 4.0.
What is Partitioned Sequential Messaging
mainPartitioned Sequential Messaging is a feature designed to manage concurrency by guaranteeing sequential processing within specific groups of messages (e.g., messages related to the same business entity like an
Order) while allowing parallel processing between different groups. This prevents race conditions and incorrect system states caused by simultaneous writes to the same entity or event stream.Wolverine currently supports this for:
- Purely local processing within the current process.
- Partitioned publishing to external transports (like RabbitMQ or Amazon SQS) across a range of queues.
- Partitioned processing of messages received from external transports within a single process.
What is a Saga in Wolverine
mainIn Wolverine, a Saga (also known as a process manager) is a long-running, multi-step process used to coordinate workflows or break large transactions into smaller steps by tracking state between messages.
A stateful saga consists of four components:
- A Saga State Document: A type that inherits from
Wolverine.Saga. This type also serves as the handler for messages impacting the saga. - Messages: Specific message types that trigger updates to the saga state.
- A Persistence Strategy: A registered strategy (e.g., Marten) that knows how to load and save the saga state documents.
- An Identity: A unique identifier used to save, load, or delete the current saga state.
Important: Do not call
IMessageBus.InvokeAsync()within a Saga handler to execute a command on that same Saga. This can lead to acting on stale or missing data. Instead, use cascading messages for subsequent work.- A Saga State Document: A type that inherits from
What is Conjoined Multi-Tenancy in Wolverine?
mainConjoined Multi-Tenancy is a mode for EF Core in Wolverine that enables shared-database tenancy. Unlike the 'DB-per-tenant' mode, conjoined mode uses a single database where multiple tenants coexist in the same tables, distinguished by a
tenant_idcolumn.When an EF entity implements the
ITenantedinterface, Wolverine automatically handles:- Mapping the
tenant_idcolumn. - Binding a global query filter to the ambient Wolverine tenant.
- Stamping the tenant ID on inserts.
- Rejecting cross-tenant writes.
This mode is a sibling to the existing
AddDbContextWithWolverineManagedMultiTenancy(DB-per-tenant) and they are mutually exclusive perDbContext.- Mapping the
Use IHttpAware to automate endpoint metadata
mainYou can implement the
IHttpAwareinterface on your response types to automatically apply metadata and HTTP runtime behavior (like status codes and headers) to any endpoint that returns that type. This ensures that your custom types are correctly reflected in exported OpenAPI documentation.public record CreationResponse([StringSyntax("Route")] string Url) : IHttpAware { public static void PopulateMetadata(MethodInfo method, EndpointBuilder builder) { builder.RemoveStatusCodeResponse(200); // ... logic to add 201 status code and type } void IHttpAware.Apply(HttpContext context) { context.Response.Headers.Location = Url; context.Response.StatusCode = 201; } }