6.0 KiB
Architecture
Svrnty.CQRS is a modular CQRS/event-sourcing framework for .NET 10, organized as 18 NuGet packages with clear separation of concerns.
Package Dependency Graph
Svrnty.CQRS.Abstractions
(ICommandHandler, IQueryHandler)
|
+-----------------+-----------------+
| |
Svrnty.CQRS Svrnty.CQRS.FluentValidation
(Discovery, Registration, (AbstractValidator<T> binding)
CqrsBuilder, DI) depends on: Abstractions, Core
|
+------------+------------+---------------------------+
| | | |
MinimalApi Grpc DynamicQuery Sagas
(HTTP REST) (gRPC) (Filtering, (Orchestrator,
| Sorting, Paging) Compensation)
| | |
Grpc.Abstractions DQ.Abstractions Sagas.Abstractions
(GrpcIgnore attr) (IQueryableProvider) (ISaga, ISagaBuilder,
| | | ISagaOrchestrator)
Grpc.Generators DQ.MinimalApi | |
(Source gen, (HTTP endpoints | Sagas.RabbitMQ
.proto gen) for DQ) | (RabbitMQ transport)
|
DQ.EntityFramework
(EF Core provider)
Events.Abstractions Notifications.Abstractions
(IDomainEvent, (INotificationPublisher,
IDomainEventPublisher) StreamingNotificationAttribute)
| |
Events.RabbitMQ Notifications.Grpc
(RabbitMQ transport) (gRPC streaming)
Dependency Matrix
| Package | Depends On (internal) |
|---|---|
Svrnty.CQRS.Abstractions |
(none) |
Svrnty.CQRS |
Abstractions |
Svrnty.CQRS.MinimalApi |
Abstractions, Core |
Svrnty.CQRS.Grpc |
Core |
Svrnty.CQRS.Grpc.Abstractions |
(none) |
Svrnty.CQRS.Grpc.Generators |
(none, Roslyn source gen) |
Svrnty.CQRS.FluentValidation |
Abstractions, Core |
Svrnty.CQRS.DynamicQuery.Abstractions |
(none) |
Svrnty.CQRS.DynamicQuery |
DynamicQuery.Abstractions, Core |
Svrnty.CQRS.DynamicQuery.MinimalApi |
Abstractions, DynamicQuery.Abstractions, DynamicQuery |
Svrnty.CQRS.DynamicQuery.EntityFramework |
DynamicQuery |
Svrnty.CQRS.Events.Abstractions |
(none) |
Svrnty.CQRS.Events.RabbitMQ |
Events.Abstractions |
Svrnty.CQRS.Sagas.Abstractions |
(none) |
Svrnty.CQRS.Sagas |
Core, Sagas.Abstractions |
Svrnty.CQRS.Sagas.RabbitMQ |
Sagas |
Svrnty.CQRS.Notifications.Abstractions |
(none) |
Svrnty.CQRS.Notifications.Grpc |
Notifications.Abstractions |
CQRS Data Flow
Command Flow
Client Request
|
v
[MinimalApi POST /api/command/{name}] or [gRPC CommandService/{name}]
|
v
FluentValidation (if validator registered)
|
|-- Validation fails --> RFC 7807 ProblemDetails (HTTP) / Google Rich Error (gRPC)
|
v
ICommandHandler<TCommand, TResult>.HandleAsync(command, ct)
|
v
Command Result (or void)
|
+--> (optional) IDomainEventPublisher.PublishAsync(event)
+--> (optional) INotificationPublisher.PublishAsync(notification)
Query Flow
Client Request
|
v
[MinimalApi POST /api/query/{name}] or [gRPC QueryService/{name}]
|
v
IQueryHandler<TQuery, TResult>.HandleAsync(query, ct)
|
v
Query Result
Dynamic Query Flow
Client Request (with filters, sorts, pagination)
|
v
[MinimalApi POST /api/dynamic-query/{entity}]
|
v
IQueryableProvider<TSource>.GetQueryableAsync(query, ct)
|
v
PoweredSoft.DynamicQuery engine (applies filters, sorts, groups, aggregates)
|
v
IAlterQueryableService (optional interception)
|
v
Paged/Grouped result set
Saga Flow
ISagaOrchestrator.StartAsync<TSaga, TData>(data)
|
v
ISaga<TData>.Configure(builder) -- defines steps
|
v
Step 1: Execute --> Step 2: Execute --> Step 3: Execute --> Completed
| | |
| | +-- fails -->
| | |
| +-- compensate <-----------------+
| |
+-- compensate <-----------------+
|
v
Compensated (rolled back)
Separation of Concerns
The framework follows a layered architecture:
-
Abstractions layer (4 packages) -- Pure interfaces and marker types with zero dependencies. Can be referenced by any project without pulling in implementation details.
Svrnty.CQRS.AbstractionsSvrnty.CQRS.DynamicQuery.AbstractionsSvrnty.CQRS.Events.AbstractionsSvrnty.CQRS.Sagas.AbstractionsSvrnty.CQRS.Grpc.AbstractionsSvrnty.CQRS.Notifications.Abstractions
-
Core layer (1 package) -- Handler discovery, DI registration, and the
CqrsBuilderfluent API.Svrnty.CQRS
-
Transport layer (4 packages) -- Maps commands/queries to HTTP or gRPC endpoints.
Svrnty.CQRS.MinimalApiSvrnty.CQRS.GrpcSvrnty.CQRS.Grpc.GeneratorsSvrnty.CQRS.DynamicQuery.MinimalApi
-
Feature layer (4 packages) -- Optional capabilities that can be composed in.
Svrnty.CQRS.FluentValidationSvrnty.CQRS.DynamicQuerySvrnty.CQRS.DynamicQuery.EntityFrameworkSvrnty.CQRS.Sagas
-
Infrastructure layer (3 packages) -- Concrete transport bindings for messaging and streaming.
Svrnty.CQRS.Events.RabbitMQSvrnty.CQRS.Sagas.RabbitMQSvrnty.CQRS.Notifications.Grpc
This layering ensures that application code depends only on abstractions, while transport and infrastructure concerns remain pluggable.