Eladei.Architecture.Tests.EntityFramework
1.0.0
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package Eladei.Architecture.Tests.EntityFramework --version 1.0.0
NuGet\Install-Package Eladei.Architecture.Tests.EntityFramework -Version 1.0.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="Eladei.Architecture.Tests.EntityFramework" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Eladei.Architecture.Tests.EntityFramework" Version="1.0.0" />
<PackageReference Include="Eladei.Architecture.Tests.EntityFramework" />
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 Eladei.Architecture.Tests.EntityFramework --version 1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Eladei.Architecture.Tests.EntityFramework, 1.0.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 Eladei.Architecture.Tests.EntityFramework@1.0.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=Eladei.Architecture.Tests.EntityFramework&version=1.0.0
#tool nuget:?package=Eladei.Architecture.Tests.EntityFramework&version=1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Eladei.Architecture
Lightweight CQRS + DDD / Entity Framework Executor for .NET
Eladei.Architecture is a set of libraries for implementing commands and queries with support for CQRS, DDD, EF Core, and Outbox.
Библиотеки
| Библиотека | Назначение |
|---|---|
Eladei.Architecture.Cqrs |
Base abstractions and classes for working with commands and queries. |
Eladei.Architecture.Cqrs.Ddd |
Command and query implementation with DDD support. Commands and queries operate on the domain model (Application Layer). |
Eladei.Architecture.Cqrs.EntityFramework |
Command and query implementation using EF Core in the Transaction Script style. Commands and queries can be part of the Domain Layer. |
Eladei.Architecture.Ddd |
Base types for implementing tactical DDD patterns. |
Eladei.Architecture.Jobs.Quartz |
Helper classes for working with Quartz. |
Eladei.Architecture.Logging |
Base types for logging. |
Eladei.Architecture.Messaging |
Base types for integration event processing. |
Eladei.Architecture.Messaging.Kafka |
Types for working with integration events via Kafka. |
Eladei.Architecture.Tests.EntityFramework |
Base types for building integration and unit tests focused on Entity Framework. |
Основные концепции
Команды
- Executed through
DddCommandExecutororEfCommandExecutor. - Can persist domain events into the Outbox.
- Outbox — ensures reliable message delivery: command execution results and events are stored within the same transaction, while event publishing is performed by a separate process.
- If an error occurs, the transaction is rolled back, and neither events nor execution results are persisted.
Запросы
- Executed through
DddQueryExecutororEfQueryExecutor. - Return read models without modifying state.
Outbox
- After successful command execution, all domain events are stored in the Outbox.
- Can be integrated with a message bus or another event-processing mechanism.
- Atomicity is guaranteed: either both command results and events are persisted, or everything is rolled back.
Quick Examples
1. EF example (transaction script)
// Command executor
var commandExecutor = new EfCommandExecutor<BookRatingDbContext>(
contextFactory,
new MockOperationExecutionPolicyService(),
new MockOutboxDomainEventDao(eventDaoLogger));
// Query executor
var queryExecutor = new EfQueryExecutor<BookRatingDbContext>(contextFactory);
// Execute command
var registerBookCommand = new RegisterBookCommand("Капитанская дочка", "А.С.Пушкин");
var bookId = await commandExecutor.ExecuteAsync(registerBookCommand, CancellationToken.None);
// Execute query
var findBookQuery = new FindBookByIdQuery(bookId);
var bookInfo = await queryExecutor.ExecuteAsync(findBookQuery, CancellationToken.None);
EF Command Executor Workflow
flowchart TD
A["Input Command"] --> B["EfCommandExecutor"]
B --> C["Get Execution Policy (retry)"]
C --> D["Attempt Execution (up to MaxAttempts)"]
D --> E["BeforeExecuteAsync"]
E --> F["Create DbContext & Begin Transaction"]
F --> G["ExecuteAsync"]
G --> H{"Has Domain Events?"}
H -->|Yes| I["Save Domain Events (Outbox)"]
H -->|No| J["Skip"]
I --> J["SaveChangesAsync"]
J --> K["Commit Transaction"]
F -->|Exception| L["Rollback Transaction"]
L --> M{"Attempts < MaxAttempts?"}
M -->|Yes| D
M -->|No| N["Throw Exception"]
K --> O["Return Result"]
EF Query Executor Workflow
flowchart TD
A["Input Query"] --> B["EfQueryExecutor"]
B --> C["Create DbContext"]
C --> D["Execute Query (ExecuteAsync)"]
D --> E{"Exception?"}
E -->|OperationCanceledException| F["Log Cancelled & throw"]
E -->|Other Exception| G["Log Critical & throw"]
E -->|No Exception| H["Return Result"]
2. DDD Example (Application Layer + Domain Model)
// Command executor
var commandExecutor = new DddCommandExecutor(
contextFactory,
new MockOperationExecutionPolicyService(),
new MockOutboxDomainEventDao(eventDaoLogger));
// Query executor
var queryExecutor = new DddQueryExecutor(contextFactory);
// Execute command
var registerBookCommand = new RegisterBookCommand("Капитанская дочка", "А.С. Пушкин");
var bookId = await _commandExecutor.ExecuteAsync(registerBookCommand, CancellationToken.None);
// Execute query
var query = new FindBookByIdQuery(bookId);
var foundBook = await queryExecutor.ExecuteAsync(query, CancellationToken.None);
DDD Command Executor Workflow
flowchart TD
A["Input Command"] --> B["DddCommandExecutor"]
B --> C["Get Execution Policy (retry)"]
C --> D["Attempt Execution (up to MaxAttempts)"]
D --> E["BeforeExecuteAsync"]
E --> F["Create UnitOfWork Context & Begin Transaction"]
F --> G["ExecuteAsync"]
G --> H{"Are there domain events?"}
H -->|Yes| I["Save Domain Events (Outbox)"]
H -->|No| J["Skip domain events"]
I --> J["Save Changes (SaveChangesAsync)"]
J --> K["Commit Transaction"]
F -->|Exception| L["Rollback Transaction"]
L --> M{"Attempt < MaxAttempts?"}
M -->|Yes| D
M -->|No| N["Throw Exception"]
K --> O["Return Result / Finish"]
DDD Query Executor Workflow
flowchart TD
A["Input Query"] --> B["DddQueryExecutor"]
B --> C["Create UnitOfWork Context"]
C --> D["ExecuteAsync Query"]
D --> E{"Exception?"}
E -->|OperationCanceledException| F["Log Cancelled & Throw"]
E -->|Other Exception| G["Wrap in QueryExecutingErrorException & Throw"]
E -->|No Exception| H["Log Success"]
H --> I["Return Result"]
Notes
- In the EF scenario, commands interact directly with the database through the DbContext (Transaction Script).
- In the DDD scenario, commands operate through the Application Layer by modifying aggregates and producing domain events.
- Command execution results and Outbox events are persisted only after a successful transaction commit.
Full examples: /samples/ConsoleExamples
Samples
ConsoleExamples
- CqrsWithDddExecuting - console application demonstrating command and query execution using the DDD approach.
- CqrsWithEntityFrameworkExecuting - console application demonstrating command and query execution using the Transaction Script approach with Entity Framework.
Notes
The DDD-based domain model is intentionally simplified to demonstrate how the library works. In real-world projects, DDD should only be used for complex business logic.
Microservices (production-ready)
- BookRating: CQRS + transaction script + Outbox + Kafka
- BookInfo: CQRS + transaction script + Outbox + Kafka
Roadmap / TODO
- Unit tests for CQRS libraries (planned)
- Unit and integration tests for microservice samples
- Example microservice with a full-featured DDD implementation
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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.
-
net9.0
- Microsoft.NET.Test.Sdk (>= 18.3.0)
- Moq.EntityFrameworkCore (>= 9.0.0.10)
- Npgsql.EntityFrameworkCore.PostgreSQL (>= 9.0.4)
- xunit.v3 (>= 3.2.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.