Tooark.Mediator.EntityFrameworkCore
4.5.0
See the version list below for details.
dotnet add package Tooark.Mediator.EntityFrameworkCore --version 4.5.0
NuGet\Install-Package Tooark.Mediator.EntityFrameworkCore -Version 4.5.0
<PackageReference Include="Tooark.Mediator.EntityFrameworkCore" Version="4.5.0" />
<PackageVersion Include="Tooark.Mediator.EntityFrameworkCore" Version="4.5.0" />
<PackageReference Include="Tooark.Mediator.EntityFrameworkCore" />
paket add Tooark.Mediator.EntityFrameworkCore --version 4.5.0
#r "nuget: Tooark.Mediator.EntityFrameworkCore, 4.5.0"
#:package Tooark.Mediator.EntityFrameworkCore@4.5.0
#addin nuget:?package=Tooark.Mediator.EntityFrameworkCore&version=4.5.0
#tool nuget:?package=Tooark.Mediator.EntityFrameworkCore&version=4.5.0
Tooark.Mediator.EntityFrameworkCore
Library that moves Entity Framework Core persistence into the Tooark.Mediator pipeline, keeping handlers free of SaveChanges.
π Languages: πΊπΈ English (this file) Β· π§π· PortuguΓͺs
Contents
Overview
Every command handler ends with await context.SaveChangesAsync(...). Repeated across dozens of handlers, the line becomes noise β and forgetting it produces a command that "works" without writing anything.
The package registers a behavior in the Tooark.Mediator pipeline that persists the changes once, at the end of the command:
- handlers only describe the changes on the
DbContext; - persistence happens only when the pipeline completes without an exception;
- queries do not go through persistence;
- nested commands take part in the same unit of work.
π§ Installation
dotnet add package Tooark.Mediator.EntityFrameworkCore
βοΈ Configuration
using Tooark.Mediator.EntityFrameworkCore.Injections;
using Tooark.Mediator.Injections;
builder.Services.AddDbContext<AppDbContext>(options => options.UseNpgsql(connectionString));
builder.Services.AddTooarkMediator(typeof(Program).Assembly);
builder.Services.AddTooarkMediatorUnitOfWork<AppDbContext>();
With an explicit transaction, for when the handler persists more than once or combines the DbContext with another transactional resource:
using Tooark.Mediator.EntityFrameworkCore.Enums;
builder.Services.AddTooarkMediatorUnitOfWork<AppDbContext>(EUnitOfWorkStrategy.Transaction);
Registration order: the behavior takes the position where
AddTooarkMediatorUnitOfWorkis called, and the pipeline behaviors run in registration order. Register validation before the unit of work β it makes no sense to prepare persistence and then reject the request.
π¦ Components
Persistence strategies
| Strategy | Behavior |
|---|---|
SaveChanges |
Persists at the end of the command, with Entity Framework Core's implicit transaction |
Transaction |
Runs the command inside an explicit transaction, persisting before committing |
SaveChanges is the default and covers the common case: a single call to SaveChangesAsync is already atomic, since Entity Framework Core wraps the batch in a transaction. The explicit transaction is only needed when there is more than one persistence in the same command, or when the DbContext is combined with another transactional resource.
In the Transaction strategy, the transaction is opened inside the provider's resiliency strategy. That avoids the error that occurs when opening an explicit transaction with retries configured (EnableRetryOnFailure), but it means the operation may run more than once on a transient failure β the handler must be idempotent.
Dependency injection
TooarkDependencyInjection.AddTooarkMediatorUnitOfWork<TContext>(IServiceCollection, EUnitOfWorkStrategy)
Abstraction
IUnitOfWork(Tooark.Mediator.EntityFrameworkCore.Interfaces): exposesSaveChangesAsyncandExecuteInTransactionAsync, with no Entity Framework types, allowing the implementation to be replaced in tests.
Behavior with nested commands
A command dispatched from within another command takes part in the unit of work already started: only the outermost command persists. Without that control, the inner command would write in the middle of the outer one's operation, and a later failure would leave the database in a partial state.
Behavior with notifications
Notifications do not go through the pipeline: their handlers run inside the command handler, therefore before persistence. Whatever they write to the DbContext is saved together, in the same unit of work.
π Usage Examples
Handler without persistence
using Tooark.Mediator.Abstractions;
using Tooark.Mediator.Handlers;
public sealed record CreateProduct(string Name) : ICommand<Guid>;
public sealed class CreateProductHandler(AppDbContext context) : ICommandHandler<CreateProduct, Guid>
{
public Task<Guid> HandleAsync(CreateProduct request, CancellationToken cancellationToken = default)
{
var product = new Product(request.Name);
context.Products.Add(product);
// No SaveChanges: persistence is the pipeline's responsibility
return Task.FromResult(product.Id);
}
}
Query, which does not go through persistence
public sealed record CountProducts : IQuery<int>;
public sealed class CountProductsHandler(AppDbContext context) : IQueryHandler<CountProducts, int>
{
public Task<int> HandleAsync(CountProducts request, CancellationToken cancellationToken = default)
{
return context.Products.CountAsync(cancellationToken);
}
}
The behavior is constrained to ICommand<TResponse>, so the container skips it when dispatching the query β with no runtime type check.
Full pipeline
builder.Services.AddTooarkMediator(typeof(Program).Assembly);
builder.Services.AddTooarkMediatorBehavior(typeof(LoggingBehavior<,>));
builder.Services.AddTooarkMediatorBehavior(typeof(ValidationBehavior<,>));
builder.Services.AddTooarkMediatorUnitOfWork<AppDbContext>();
From outermost to innermost: logging, validation, unit of work and, last, the handler.
π Dependencies
| Package | Version | Usage |
|---|---|---|
Tooark.Mediator |
4.x | Behavior pipeline and registration |
Tooark.Mediator.Abstractions |
4.x | Message contracts (ICommand) |
Tooark.Exceptions |
4.x | Configuration errors |
Microsoft.EntityFrameworkCore |
8.x/10.x | Context, persistence and transactions |
Microsoft.Extensions.DependencyInjection.Abstractions |
8.x/10.x | Container registration |
The package is part of the Tooark aggregator, so whoever installs Tooark already gets it.
πͺͺ Contributing
Contributions are welcome! Feel free to open issues and pull requests in the Tooark.Mediator.EntityFrameworkCore repository.
π License
This project is licensed under the BSD 3-Clause License. See the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. 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 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. |
-
net10.0
- Microsoft.EntityFrameworkCore (>= 10.0.12)
- Microsoft.Extensions.Caching.Memory (>= 10.0.12)
- Microsoft.Extensions.DependencyInjection (>= 10.0.12)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
- Microsoft.Extensions.Options (>= 10.0.12)
- Tooark.Exceptions (>= 4.5.0)
- Tooark.Mediator (>= 4.5.0)
- Tooark.Mediator.Abstractions (>= 4.5.0)
-
net8.0
- Microsoft.EntityFrameworkCore (>= 8.0.31)
- Microsoft.Extensions.Caching.Memory (>= 8.0.1)
- Microsoft.Extensions.DependencyInjection (>= 8.0.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options (>= 8.0.2)
- Tooark.Exceptions (>= 4.5.0)
- Tooark.Mediator (>= 4.5.0)
- Tooark.Mediator.Abstractions (>= 4.5.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Tooark.Mediator.EntityFrameworkCore:
| Package | Downloads |
|---|---|
|
Tooark
Package with all Tooark resources for .NET applications. |
GitHub repositories
This package is not used by any popular GitHub repositories.