Messaging

Wolverine Best Practices Revisited: A-Frame and Handler Design

JasperFx rewrote the Wolverine best practices guide from scratch, replacing the 2023 version. The new guide centers on the A-Frame Architecture and gives concrete advice on splitting handlers, error handling, and at-least-once messaging rules. It is a practical reference for .NET teams building messaging systems with Wolverine.

Published
Reading time
26 min read
agent run #15
agent run #15
Go to original jasperfx.net

Report this story

Is something wrong with the summary, or do you own this content? Your message comes straight to my inbox.

Type of message

Key points

  • Write handlers as business logic: load data in LoadAsync() and make decisions in Handle()
  • Use the [Entity] attribute and return values such as Storage.Update() for persistence
  • Return outgoing messages as cascading messages from the root handler so side effects are visible
  • Validate with a Validate() method, Data Annotations, or FluentValidation; no Result<T> wrappers needed
  • For new code, use Wolverine.HTTP endpoints directly instead of a controller calling a mediator
  • Avoid calling handlers from other handlers via InvokeAsync(), which hides nested transactions and round trips

The Wolverine best practices page dated from 2023, when the library was young, and it no longer reflects many of its features. Author Jeremy Miller explains that the team rewrote the guide from scratch. The new version puts the A-Frame approach first, which separates business logic from infrastructure, and it gives advice on dividing handlers by category and handling errors.

The core idea is to keep handler methods close to pure functions. Data loading goes into a separate LoadAsync() method, while decisions stay in Handle(). Wolverine generates the coordination code around the handler. Persistence uses the [Entity] attribute, and side effects are expressed through return values and cascading messages. The guide also argues against repository wrappers and against nesting handlers through InvokeAsync(), since both hide round trips and transaction boundaries.

Real-world use

  • Keeping invoice payment rules in handlers that can be unit tested without a database or host
  • Making a order-processing service's outgoing messages traceable from the handler signature
  • Migrating an MVC controller and mediator setup to Wolverine.HTTP endpoints step by step

Why it matters

Writing handlers in the A-Frame style lets you test business rules without a database, and keeping data access beside the handler makes round trips visible so you can batch them.

This summary was generated by the agent from the original post on JasperFx (Critter Stack) Blog. The full text and all rights belong to its author and publisher. Go to original

Related stories

Feedback

Found a bug or have an idea? Your message lands straight in my inbox.

Type of message