![]() |
VOOZH | about |
dotnet add package Hexalith.EventStore.SignalR --version 3.15.1
NuGet\Install-Package Hexalith.EventStore.SignalR -Version 3.15.1
<PackageReference Include="Hexalith.EventStore.SignalR" Version="3.15.1" />
<PackageVersion Include="Hexalith.EventStore.SignalR" Version="3.15.1" />Directory.Packages.props
<PackageReference Include="Hexalith.EventStore.SignalR" />Project file
paket add Hexalith.EventStore.SignalR --version 3.15.1
#r "nuget: Hexalith.EventStore.SignalR, 3.15.1"
#:package Hexalith.EventStore.SignalR@3.15.1
#addin nuget:?package=Hexalith.EventStore.SignalR&version=3.15.1Install as a Cake Addin
#tool nuget:?package=Hexalith.EventStore.SignalR&version=3.15.1Install as a Cake Tool
👁 GitHub stars
👁 NuGet
👁 Build
👁 Docs
If you've spent weeks wiring up an event store, a message broker, multi-tenant isolation, and a read-model refresh story — only to realize you'll do it again for your next project — we built this for you. Hexalith.EventStore is a distributed, CQRS and DDD-ready event sourcing framework that handles command routing, event persistence, snapshots, query execution, and pub/sub delivery so you can focus on domain logic. Built on DAPR for infrastructure portability.
Your domain logic lives in an aggregate class with typed Handle methods — conceptually a pure function: $(Command, CurrentState?) \rightarrow List<DomainEvent>$. Each Handle method receives a specific command and the current state, then returns a DomainResult carrying success events or rejections.
public sealed class CounterAggregate : EventStoreAggregate<CounterState>
{
public static DomainResult Handle(IncrementCounter command, CounterState? state)
=> DomainResult.Success(new IEventPayload[] { new CounterIncremented() });
public static DomainResult Handle(DecrementCounter command, CounterState? state)
{
if ((state?.Count ?? 0) == 0)
return DomainResult.Rejection(new IRejectionEvent[] { new CounterCannotGoNegative() });
return DomainResult.Success(new IEventPayload[] { new CounterDecremented() });
}
public static DomainResult Handle(ResetCounter command, CounterState? state)
{
if ((state?.Count ?? 0) == 0)
return DomainResult.NoOp();
return DomainResult.Success(new IEventPayload[] { new CounterReset() });
}
}
public sealed class CounterState
{
public int Count { get; private set; }
public void Apply(CounterIncremented e) => Count++;
public void Apply(CounterDecremented e) => Count--;
public void Apply(CounterReset e) => Count = 0;
}
Under the hood,
EventStoreAggregate<TState>implementsIDomainProcessor— you can still use that interface directly for advanced scenarios (see the legacy example).
| Feature | Hexalith | Marten | EventStoreDB | Custom |
|---|---|---|---|---|
| Infrastructure portability | Any store/broker, zero-code swap | PostgreSQL only | Dedicated server | You build it |
| Multi-tenant isolation | Built-in: data, topics, access | Manual | Manual | You build it |
| CQRS/ES framework | Complete, infra-agnostic | Complete, PG-coupled | Storage only, BYO framework | You build it |
| Deployment | DAPR sidecar: Docker, K8s, ACA | App library | Server + clients | You build it |
| Database lock-in | None (Redis, PG, Cosmos, etc.) | PostgreSQL | EventStoreDB | Chosen DB |
Note: Hexalith is not the right tool for every scenario. If you need raw event stream performance or already run PostgreSQL everywhere, see the .
Register the event store in two lines — AddEventStore() scans your assembly for aggregate types, no manual registration needed:
builder.Services.AddEventStore(); // Auto-discovers CounterAggregate
// ...
app.UseEventStore(); // Activates domains with convention-derived names
Beyond commands, the platform includes a query pipeline with ETag-based cache validation, projection invalidation hooks, preflight authorization endpoints, and optional SignalR notifications for real-time read-model refresh.
Get started in under 10 minutes — follow the .
Prerequisites: .NET SDK, Docker Desktop, DAPR CLI
flowchart TB
Client([Client Application]) -->|REST commands + queries| CommandAPI[Command API Gateway]
Realtime[Realtime UI / Client] <-.->|SignalR change notifications| CommandAPI
CommandAPI -->|Route command| Actor[Aggregate Actor]
Actor -->|Invoke| Domain[Domain Service<br/>IDomainProcessor]
Domain -->|Return events| Actor
Actor -->|Persist| StateStore[(State Store<br/>Redis / PostgreSQL / Cosmos DB)]
Actor -->|Publish| PubSub{{Pub/Sub<br/>RabbitMQ / Kafka / Azure Service Bus}}
PubSub -->|Subscribe| Projections[Event Handlers / Projections]
Projections -->|Projection changed| CommandAPI
subgraph DAPR ["DAPR Sidecar (Infrastructure Abstraction)"]
StateStore
PubSub
end
<details> <summary>Architecture diagram text description</summary>
The system follows a command-event architecture with a built-in read-model refresh path: client applications send commands and queries via REST to the Command API Gateway, which routes commands to Aggregate Actors and queries to projection handlers. Each actor invokes the domain service (your IDomainProcessor implementation) and persists resulting events to a state store. Events are published to a pub/sub system for downstream consumers, and projection changes can be surfaced back to clients through HTTP cache validators and optional SignalR notifications. DAPR provides the infrastructure abstraction layer, allowing you to swap state stores (Redis, PostgreSQL, Cosmos DB) and message brokers (RabbitMQ, Kafka, Azure Service Bus) without changing application code.
</details>
Full documentation index:
Contributions are welcome! Please read the and before submitting a pull request.
This project is licensed under the .
See the for release history and notable changes.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 net10.0 is compatible. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
This package is not used by any NuGet packages.
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 3.15.1 | 106 | 5/9/2026 |
| 3.15.0 | 99 | 5/9/2026 |
| 3.14.2 | 107 | 5/9/2026 |
| 3.14.1 | 96 | 5/7/2026 |
| 3.14.0 | 98 | 5/7/2026 |
| 3.13.5 | 91 | 5/7/2026 |
| 3.13.4 | 98 | 5/7/2026 |
| 3.13.3 | 93 | 5/6/2026 |
| 3.13.2 | 90 | 5/6/2026 |
| 3.13.1 | 86 | 5/6/2026 |
| 3.13.0 | 92 | 5/5/2026 |
| 3.12.0 | 86 | 5/5/2026 |
| 3.11.1 | 91 | 5/5/2026 |
| 3.11.0 | 92 | 5/5/2026 |
| 3.10.0 | 92 | 5/5/2026 |
| 3.9.1 | 94 | 5/4/2026 |
| 3.9.0 | 105 | 5/3/2026 |
| 3.8.0 | 95 | 5/3/2026 |
| 3.7.0 | 92 | 5/3/2026 |
| 3.6.0 | 100 | 5/3/2026 |