Wolverine + Marten: My story and subjective take

Introduction

If you’re a .NET developer who’s heard about Wolverine and Martenbut haven’t yet taken the plunge, this article might be for you.

I come from what you could call the “old dog” camp—spending most of my career with EF Core, Dappe…


This content originally appeared on DEV Community and was authored by Tran Manh Hung

Introduction

If you're a .NET developer who's heard about Wolverine and Martenbut haven't yet taken the plunge, this article might be for you.

I come from what you could call the "old dog" camp—spending most of my career with EF Core, Dapper, and the classic Controller-based approach. (Yes, I still write controllers instead of going all-in with minimal APIs—though I've dabbled with them in a few isolated scenarios.)

What follows is my personal story: moving from skepticism to cautious optimism as I started exploring Wolverine and Marten. Along the way I'll highlight the mistakes I made, the lessons I learned, and why these tools might (or might not) be worth your attention.

And just to be clear—this is a subjective take. And I am in still in the learning phase. So take it with a grain of salt. Don't be another AI that will keep glazing me that I am totally right. Feel free to fix any errors i made.

Alright lets start...

The Traditional .NET Web API Way

Most of us .NET developers are comfortable with the controller-based approach:

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    private readonly IProductService _productService;

    [HttpPost]  
    public async Task<ActionResult> CreateProduct(CreateProductRequest request)
    {
        var result = await _productService.CreateProductAsync(request);
        return Ok(result);
    }
}

It's familiar, well-documented, and works. So why change?

What Are Wolverine and Marten?

Marten is a .NET document database and event store built on PostgreSQL. Think of it as a sophisticated ORM that treats PostgreSQL as both a relational and document database.

Wolverine is a messaging framework that handles command/query processing, with built-in support for Marten's event sourcing capabilities.

Together, they form a stack for building event-driven, DDD-focused applications.

The Half-Baked Approach (Don't Do This)

When I inherited my current project, it was using Wolverine purely as a mediator pattern replacement:

// This is the WRONG way - just using Wolverine as MediatR
public class CreateProductHandler
{
    public async Task<ProductResponse> Handle(CreateProductCommand command)
    {
        // Traditional service calls, no events, no aggregates
        // Just replacing MediatR with Wolverine
    }
}

This is the worst of both worlds. You get:

  • All the learning curve of a new framework
  • None of the actual benefits
  • More ceremony than traditional controllers
  • Confused team members

If you're going to use Wolverine, don't just use it as a fancy mediator. That's like buying Škoda car to use as a bicycle rack.

Embrace the Full Stack

After struggle and intensive documentation reading, I realized the power comes from embracing the entire paradigm:

1. Aggregate-Driven Design

public class Product
{
    public string Name { get; private set; }
    public decimal Price { get; private set; }

    public static Product Create(string name, decimal price)
    {
        var product = new Product();
        product.Apply(new ProductCreated(Guid.NewGuid(), name, price));
        return product;
    }

    public void Apply(ProductCreated @event)
    {
        Id = @event.ProductId;
        Name = @event.Name;
        Price = @event.Price;
    }   
}

2. Command Handlers That Work With Aggregates

public static class ProductHandlers
{
    public static ProductCreated Handle(CreateProduct command, IDocumentSession session)
    {
        var product = Product.Create(command.Name, command.Price);
        session.Store(product);

        return new ProductCreated(product.Id, command.Name, command.Price);
    }
}

Or even better you can not use command at all

public static class ProductHandlers
{
    [AggregateHandler]
    [WolverinePost("/product"), EmptyResponse]
    public static ProductCreated CreateProduct(CreateProduct command)
    {
        var product = Product.Create(command.Name, command.Price);        
        return new ProductCreated(product.Id, command.Name, command.Price);
    }
}

3. Event-Driven Projections

public class ProductProjection : SingleStreamProjection<ProductSummary>
{
    public ProductSummary Create(ProductCreated created)
    {
        return new ProductSummary
        {
            Id = created.ProductId,
            Name = created.Name,
            Price = created.Price
        };
    }
}

The Transformation Results

Code Volume Reduction

By my totally subjective eye i think codebase shrunk by about 30%. No more:

  • Separate DTOs for every operation
  • Mapping between entities and DTOs
  • Complex repository patterns
  • Manual change tracking

Ok so main points

1. Start Small

Don't rewrite everything at once. Pick a bounded context and migrate gradually.

2. Invest in Learning

Don't half-ass it. Read the documentation thoroughly. Understand DDD principles. Your team needs to really understand the concepts, not just copy-paste code.

3. Embrace Events

Stop thinking in CRUD terms. Think in business events. "ProductCreated," "PriceChanged," "ProductDiscontinued."

4. Use Projections Wisely

Create read models that match your UI needs. Don't try to make one projection serve all purposes.

5. PostgreSQL over SQL Server

Remember, you're not just using a document database - you have all of PostgreSQL's power available for complex queries. Although this may not be up to date anymore (https://learn.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server?view=sql-server-ver17)

Sample Project Structure

/Domain
  /Products
    Product.cs (Aggregate)
    ProductEvents.cs 
/Handlers
  ProductHandlers.cs
/Projections
  ProductProjections.cs
Program.cs 

My take

After about two to three weeks of learning (and I'm still learning), I've noticed that even my junior developers are coding faster and delivering features more smoothly. The initial skepticism I had slowly gave way to optimism as my concerns were put to the test.

At first, I thought using Marten was just reinventing the wheel. Why not simply stick with Entity Framework and MediatR? But as I dug deeper, I realized that while EF is excellent at what it does, Marten's hybrid approach of documents and relational data solves problems that EF tends to complicate. Event sourcing, projections, and complex querying become much more natural to work with, instead of feeling bolted on.

Another doubt I had was the risk of relying on a non-Microsoft library. What if the maintainers abandon it? To my surprise, I found that the project is actively maintained, backed by a strong community, and growing steadily. And even in the worst case, the data remains safe in PostgreSQL, and the design patterns I've learned are transferable to other systems.

Finally, I worried that the learning curve would be too steep for my team, especially for junior developers. I assumed they'd get lost in the concepts. But once they grasped the fundamentals of aggregates and events, the patterns began to feel intuitive. With the framework handling much of the heavy lifting, the adoption was far smoother than I expected.

Summary

Is Wolverine + Marten for everyone? No.

Is it worth considering if you're building event-driven, domain-rich applications? Ye

The key is commitment. Don't use Wolverine as a drop-in MediatR replacement. Embrace the aggregate approach, think in events, and leverage PostgreSQL's strengths. The payoff is

My advice: Build a small proof of concept, read the documentation religiously, and be prepared for a mindset shift.

Message to the Wolverine/Marten authors: If you notice unusual traffic spikes in your documentation in the last few weeks, im so sorry.


This content originally appeared on DEV Community and was authored by Tran Manh Hung


Print Share Comment Cite Upload Translate Updates
APA

Tran Manh Hung | Sciencx (2025-09-17T21:38:00+00:00) Wolverine + Marten: My story and subjective take. Retrieved from https://www.scien.cx/2025/09/17/wolverine-marten-my-story-and-subjective-take/

MLA
" » Wolverine + Marten: My story and subjective take." Tran Manh Hung | Sciencx - Wednesday September 17, 2025, https://www.scien.cx/2025/09/17/wolverine-marten-my-story-and-subjective-take/
HARVARD
Tran Manh Hung | Sciencx Wednesday September 17, 2025 » Wolverine + Marten: My story and subjective take., viewed ,<https://www.scien.cx/2025/09/17/wolverine-marten-my-story-and-subjective-take/>
VANCOUVER
Tran Manh Hung | Sciencx - » Wolverine + Marten: My story and subjective take. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/17/wolverine-marten-my-story-and-subjective-take/
CHICAGO
" » Wolverine + Marten: My story and subjective take." Tran Manh Hung | Sciencx - Accessed . https://www.scien.cx/2025/09/17/wolverine-marten-my-story-and-subjective-take/
IEEE
" » Wolverine + Marten: My story and subjective take." Tran Manh Hung | Sciencx [Online]. Available: https://www.scien.cx/2025/09/17/wolverine-marten-my-story-and-subjective-take/. [Accessed: ]
rf:citation
» Wolverine + Marten: My story and subjective take | Tran Manh Hung | Sciencx | https://www.scien.cx/2025/09/17/wolverine-marten-my-story-and-subjective-take/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.