πŸš€ Memoria™

May 16, 2026 Β· View on GitHub

From Latin memoria (memory)

.Build

.NET framework implementing DDD, CQRS, and Event Sourcing.

Memoria is extremely flexible and expandable. It can be used as a simple mediator or as a full Event Sourcing solution with Cosmos DB or Entity Framework Core as storage.

⭐ Give a star

If you're using this repository for your learning, samples, workshop, or your project, please give a star. Thank you!

⚑Main Features

  • Mediator with commands, queries, and notifications
  • Multiple aggregates per stream
  • Option to store the aggregate snapshot alongside events for fast reads and write model strongly consistent
  • Four different read modes that allow multiple write/read patterns based on specific needs.
  • In memory aggregate reconstruction up to a specific event sequence or date if provided (soon up to aggregate version)
  • Events applied to the aggregate filtered by event type
  • Events applied to the aggregate filtered by event property (key/value pairs declared on the aggregate id)
  • Retrieval of all events applied to an aggregate
  • Querying stream events from or up to a specific event sequence or date/date range
  • Querying stream events filtered by event type and/or event property
  • Optimistic concurrency control with an expected event sequence
  • Automatic event/notification publication after a command is successfully processed that returns a list of results from all notification handlers
  • Automatic event/message publication after a command is successfully processed using Service Bus or RabbitMQ
  • Automatic command validation with FluentValidation if required
  • Command sequences that return a list of results from all commands in the sequence
  • Custom command handlers or services can be used instead of the automatically resolved command handlers
  • Result pattern across handlers and providers
  • Extensible architecture with providers for store, messaging, caching, and validation

πŸ—ΊοΈ Roadmap

βœ… Recently Completed

  • New PostgreSQL companion package for the Entity Framework Core store provider that makes eventPropertyFilter work correctly against jsonb columns (uses the @> JSON-containment operator and is GIN-indexable)
  • New IEventDataFilter extension point in the Entity Framework Core store provider for plugging in provider-specific JSON filter strategies
  • New package for in-memory Service Bus for easier testing in projects using Memoria
  • New package for in-memory RabbitMQ for easier testing in projects using Memoria
  • Event property filtering across aggregates and stream queries

⏭️ Next

  • Create an ecommerce demo application to showcase Memoria features

πŸ•™ To Follow

  • Option to automatically validate commands
  • Event Grid messaging provider
  • Kafka messaging provider
  • File store provider for event sourcing
  • Amazon SQS messaging provider

πŸ“£ Release Notes

πŸ“¦ Nuget Packages

PackageLatest Stable
MemoriaNuget Package
Memoria.EventSourcingNuget Package
Memoria.EventSourcing.Store.CosmosNuget Package
Memoria.EventSourcing.Store.Cosmos.InMemoryNuget Package
Memoria.EventSourcing.Store.EntityFrameworkCoreNuget Package
Memoria.EventSourcing.Store.EntityFrameworkCore.IdentityNuget Package
Memoria.EventSourcing.Store.EntityFrameworkCore.NpgsqlNuget Package
Memoria.Messaging.RabbitMqNuget Package
Memoria.Messaging.RabbitMq.InMemoryNuget Package
Memoria.Messaging.ServiceBusNuget Package
Memoria.Messaging.ServiceBus.InMemoryNuget Package
Memoria.Validation.FluentValidationNuget Package
Memoria.Caching.RedisNuget Package
Memoria.Caching.MemoryNuget Package

πŸ”„ A taste of the API

Mediator

public record CreateProduct(string Name) : ICommand;

public class CreateProductHandler : ICommandHandler<CreateProduct>
{
    public Task<Result> Handle(CreateProduct command) =>
        Task.FromResult(Result.Ok());
}

await dispatcher.Send(new CreateProduct("Espresso"));

See the Mediator Quickstart for queries, notifications, validation, custom handlers, command sequences, and SendAndPublish.

Event Sourcing

[EventType("OrderPlaced")]
public record OrderPlaced(Guid OrderId, decimal Amount) : IEvent;

var streamId = new CustomerStreamId(customerId);
var aggregateId = new OrderAggregateId(orderId);
var order = new Order(orderId, amount: 25.45m);

await domainService.SaveAggregate(streamId, aggregateId, order, expectedEventSequence: 0);

See the Event Sourcing Quickstart for the full aggregate definition, the four read modes, multiple aggregates per stream, and in-memory replay.

πŸ“˜ Full documentation

✨ Custom Implementations and Project Support

Memoria is designed to be extensible, supporting custom store, messaging, caching, and validation providers.

Need a specific implementation for your existing code or a new provider (e.g., a custom database store or messaging bus)? I’ve got you covered! I can also work directly on your projects to implement Memoria for your specific event sourcing or CQRS needs.

Please reach out to request custom integrations, new providers, or project assistance via LinkedIn.