Cosmos.EventSourcing.CritterStack 0.1.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Cosmos.EventSourcing.CritterStack --version 0.1.0
                    
NuGet\Install-Package Cosmos.EventSourcing.CritterStack -Version 0.1.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cosmos.EventSourcing.CritterStack" Version="0.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cosmos.EventSourcing.CritterStack" Version="0.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Cosmos.EventSourcing.CritterStack" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Cosmos.EventSourcing.CritterStack --version 0.1.0
                    
#r "nuget: Cosmos.EventSourcing.CritterStack, 0.1.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Cosmos.EventSourcing.CritterStack@0.1.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Cosmos.EventSourcing.CritterStack&version=0.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Cosmos.EventSourcing.CritterStack&version=0.1.0
                    
Install as a Cake Tool

Cosmos.EventSourcing.CritterStack

NuGet

Implementación completa de Event Sourcing y CQRS usando Wolverine y Marten (CritterStack).

Descripción

Este paquete proporciona implementaciones listas para producción de todas las abstracciones definidas en Cosmos.EventSourcing.Abstractions y Cosmos.EventDriven.Abstractions. Utiliza Wolverine para mensajería y mediación, y Marten como Event Store y Document Database sobre PostgreSQL.

CritterStack es el nombre de la combinación de Wolverine + Marten, dos poderosas herramientas del ecosistema .NET.

Características

Event Store

  • MartenEventStore: Implementación de IEventStore usando Marten
  • Soporte para recuperar agregados por ID, versión o timestamp
  • Persistencia de eventos en PostgreSQL

Command Routing

  • WolverineCommandRouter: Router de comandos usando Wolverine
  • Soporte para comandos con y sin valor de retorno
  • Integración con multi-tenancy

Query Routing

  • WolverineQueryRouter: Router de consultas usando Wolverine
  • Ejecución distribuida de queries

Event Publishing

  • WolverineEventSender: Publicación de eventos usando Wolverine
  • Integración con RabbitMQ para mensajería distribuida
  • Soporte para multi-tenancy

Projection Store

  • MartenProjectionStore: Almacén de proyecciones usando Marten
  • Operaciones CRUD sobre proyecciones/vistas de lectura

Instalación

dotnet add package Cosmos.EventSourcing.CritterStack

Este paquete incluye automáticamente las dependencias de:

  • Cosmos.EventSourcing.Abstractions
  • Cosmos.EventDriven.Abstractions
  • Cosmos.MultiTenancy

Configuración

Registrar Servicios en el DI Container

using Marten;
using Wolverine;
using Cosmos.EventSourcing.CritterStack.Commands;
using Cosmos.EventSourcing.CritterStack.Queries;
using Cosmos.EventSourcing.CritterStack.Routers;

var builder = WebApplication.CreateBuilder(args);

// Configurar Marten
builder.Services.AddMarten(options =>
{
    options.Connection(builder.Configuration.GetConnectionString("Postgres")!);

    // Configurar Event Store
    options.Events.StreamIdentity = StreamIdentity.AsString;

    // Registrar agregados
    options.Events.AddEventType<OrderCreated>();
    options.Events.AddEventType<ItemAdded>();
});

// Configurar Wolverine
builder.Host.UseWolverine(opts =>
{
    // Configurar RabbitMQ para eventos públicos
    opts.UseRabbitMq("amqp://localhost")
        .AutoProvision();

    // Publicar eventos a RabbitMQ
    opts.PublishMessage<IPublicEvent>()
        .ToRabbitExchange("public-events");
});

// Registrar implementaciones de Cosmos
builder.Services.AddScoped<IEventStore, MartenEventStore>();
builder.Services.AddScoped<ICommandRouter, WolverineCommandRouter>();
builder.Services.AddScoped<IQueryRouter, WolverineQueryRouter>();
builder.Services.AddScoped<IEventSender, WolverineEventSender>();
builder.Services.AddScoped<IProjectionStore, MartenProjectionStore>();

var app = builder.Build();
app.Run();

Uso

Implementar Command Handlers con Wolverine

using Cosmos.EventSourcing.Abstractions.Commands;
using Wolverine.Attributes;

public record CreateOrder(string OrderId, string CustomerId);

// Los handlers son descubiertos automáticamente por Wolverine
public class CreateOrderHandler
{
    private readonly IEventStore _eventStore;

    public CreateOrderHandler(IEventStore eventStore)
    {
        _eventStore = eventStore;
    }

    public async Task Handle(CreateOrder command, CancellationToken ct)
    {
        var order = new Order(command.OrderId, command.CustomerId);

        _eventStore.Save(order);
        await _eventStore.SaveChangesAsync();
    }
}

Ejecutar Comandos con el Router

public class OrderController : ControllerBase
{
    private readonly ICommandRouter _commandRouter;

    public OrderController(ICommandRouter commandRouter)
    {
        _commandRouter = commandRouter;
    }

    [HttpPost]
    public async Task<IActionResult> CreateOrder(CreateOrderRequest request)
    {
        var command = new CreateOrder(Guid.NewGuid().ToString(), request.CustomerId);

        await _commandRouter.InvokeAsync(command, HttpContext.RequestAborted);

        return Ok(new { OrderId = command.OrderId });
    }
}

Implementar Query Handlers

public record GetOrderById(string OrderId);

public class GetOrderByIdHandler
{
    private readonly IProjectionStore _projectionStore;

    public GetOrderByIdHandler(IProjectionStore projectionStore)
    {
        _projectionStore = projectionStore;
    }

    public async Task<OrderDto?> Handle(GetOrderById query, CancellationToken ct)
    {
        return await _projectionStore.GetByIdAsync<OrderDto>(query.OrderId, ct);
    }
}

Publicar Eventos Públicos

using Cosmos.EventDriven.Abstractions;

public record OrderShipped(string OrderId, DateTime ShippedAt) : IPublicEvent;

public class ShipOrderHandler
{
    private readonly IEventStore _eventStore;
    private readonly IEventSender _eventSender;

    public ShipOrderHandler(IEventStore eventStore, IEventSender eventSender)
    {
        _eventStore = eventStore;
        _eventSender = eventSender;
    }

    public async Task Handle(ShipOrder command, CancellationToken ct)
    {
        var order = await _eventStore.GetAggregateRootAsync<Order>(command.OrderId, ct);

        order?.Ship();

        _eventStore.Save(order!);
        await _eventStore.SaveChangesAsync();

        // Publicar evento público a RabbitMQ
        var publicEvent = new OrderShipped(command.OrderId, DateTime.UtcNow);
        await _eventSender.PublishEventAsync(publicEvent);
    }
}

Trabajar con Proyecciones

using Cosmos.EventSourcing.Linq.Extensions;

public class OrderQueryService
{
    private readonly IQuerySession _querySession;

    public OrderQueryService(IQuerySession querySession)
    {
        _querySession = querySession;
    }

    public async Task<IReadOnlyList<OrderDto>> GetCustomerOrdersAsync(
        string customerId,
        CancellationToken ct)
    {
        var orders = await _querySession
            .Query<OrderDto>()
            .Where(o => o.CustomerId == customerId)
            .OrderByDescending(o => o.CreatedAt)
            .ToListAsync(ct);

        return orders;
    }
}

Multi-Tenancy

Este paquete incluye soporte para multi-tenancy a través de Cosmos.MultiTenancy. Los routers de comandos y queries utilizan automáticamente el TenantResolver para ejecutar operaciones en el contexto del tenant correcto.

// El WolverineCommandRouter usa automáticamente el TenantId
await _commandRouter.InvokeAsync(command, ct);
// Internamente: messageBus.InvokeForTenantAsync(tenantId, command, ct)

Requisitos

  • .NET 10.0 o superior
  • PostgreSQL 12+ (para Marten)
  • RabbitMQ (opcional, para eventos públicos)

Dependencias

  • Marten (v8.16.1) - Event Store y Document DB
  • WolverineFx (v5.4.0) - Mediación y mensajería
  • WolverineFx.Marten (v5.4.0) - Integración Wolverine-Marten
  • WolverineFx.RabbitMQ (v5.4.0) - Integración con RabbitMQ
  • Cosmos.EventSourcing.Abstractions
  • Cosmos.EventDriven.Abstractions
  • Cosmos.MultiTenancy

Recursos

Licencia

Copyright © Cosmos. Todos los derechos reservados.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Cosmos.EventSourcing.CritterStack:

Package Downloads
Cosmos.CrossCuttingConcerns.Preferences.Flagsmith

Implementación Flagsmith para Cosmos.CrossCuttingConcerns.Preferences.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.11 162 4/7/2026
0.1.10 103 4/7/2026 0.1.10 is deprecated because it has critical bugs.
0.1.9 532 3/18/2026
0.1.8 239 3/16/2026
0.1.7 142 3/12/2026
0.1.6 103 3/12/2026
0.1.5 94 3/12/2026
0.1.5-RC.1 84 3/10/2026
0.1.4 196 2/24/2026
0.1.3 290 2/23/2026
0.1.2 122 2/11/2026
0.1.1 105 2/11/2026
0.1.0 105 2/10/2026
0.0.8 101 2/9/2026
0.0.7 682 12/3/2025
0.0.6 691 12/3/2025
0.0.5 217 11/25/2025
0.0.1 310 9/19/2025