Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore
0.5.1
dotnet add package Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore --version 0.5.1
NuGet\Install-Package Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore -Version 0.5.1
<PackageReference Include="Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore" Version="0.5.1" />
<PackageVersion Include="Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore" Version="0.5.1" />
<PackageReference Include="Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore" />
paket add Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore --version 0.5.1
#r "nuget: Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore, 0.5.1"
#:package Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore@0.5.1
#addin nuget:?package=Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore&version=0.5.1
#tool nuget:?package=Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore&version=0.5.1
Cayaqui.MPS.BuildingBlocks.EntityFrameworkCore
Integración EF Core para Cayaqui.MPS.BuildingBlocks. API fiel al MPS.SharedKernel
original (PostgreSQL: Outbox usa FOR UPDATE SKIP LOCKED).
Contenido
| Área | Tipos |
|---|---|
| Outbox | OutboxMessage (EventId/EventType/retry/permanent-fail), IOutboxStore/IOutboxPurgeable, IOutboxDialect.JsonColumnType (Postgres jsonb / SqlServer nvarchar(max)), EfOutboxStore<TDbContext> (FOR UPDATE SKIP LOCKED / UPDLOCK READPAST, IAsyncDisposable), OutboxMessageConfiguration(schema?, jsonColumnType?) (provider-agnóstico: snake_case + tipo JSON inyectable + índices), OutboxRedispatchHostedService, OutboxPurgeHostedService, OutboxHealthCheck |
| Interceptors | AuditSaveChangesInterceptor (sella CreatedBy/UpdatedBy), DomainEventDispatchInterceptor (persiste eventos al outbox en la misma transacción) |
| CQRS Blazor-safe | ScopedQueryHandler<TQuery,TResponse,TDbContext>, ScopedCommandHandler<...> (ctor IServiceScopeFactory, ExecuteAsync(query, db, sp, ct) → Result<T>, DbContext efímero vía IDbContextFactory) |
| DI | AddDomainEventDispatcher(), AddOutboxRedispatchService(IConfiguration), AddModuleOutbox<TDbContext>(moduleName), AddDomainEventHandlersFromAssembly(asm) |
Setup (host)
builder.Services.AddDomainEventDispatcher();
builder.Services.AddOutboxRedispatchService(builder.Configuration); // redispatch + purge + health
builder.Services.AddScoped<ICurrentUserService, MyCurrentUserService>();
Por módulo
services.AddDbContextFactory<FinanceDbContext>((sp, o) =>
o.UseNpgsql(cs).AddInterceptors(
sp.GetRequiredService<AuditSaveChangesInterceptor>(),
sp.GetRequiredService<DomainEventDispatchInterceptor>()));
// dialect = null → autodetectado (Npgsql → Postgres, resto → SqlServer)
services.AddModuleOutbox<FinanceDbContext>("Finance");
services.AddDomainEventHandlersFromAssembly(typeof(SomeFinanceHandler).Assembly);
// FinanceDbContext.OnModelCreating
// Postgres (context-per-módulo con HasDefaultSchema):
b.ApplyConfiguration(new OutboxMessageConfiguration(jsonColumnType: new PostgresOutboxDialect().JsonColumnType));
// SQL Server / DbContext único multi-schema (pasar schema + tipo JSON explícitos):
b.ApplyConfiguration(new OutboxMessageConfiguration("common", new SqlServerOutboxDialect().JsonColumnType));
CQRS
public sealed class ListProjectsHandler(IServiceScopeFactory sf)
: ScopedQueryHandler<ListProjectsQuery, ListProjectsResponse, FinanceDbContext>(sf)
{
protected override async Task<Result<ListProjectsResponse>> ExecuteAsync(
ListProjectsQuery q, FinanceDbContext db, IServiceProvider sp, CancellationToken ct)
{
var rows = await db.Projects.AsNoTracking().ToListAsync(ct);
return new ListProjectsResponse(rows);
}
}
appsettings (opcional): Outbox:Redispatch, Outbox:Purge, Outbox:HealthCheck.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- Cayaqui.MPS.Abstractions (>= 0.2.0)
- Cayaqui.MPS.Abstractions.Validation (>= 0.1.0)
- Cayaqui.MPS.BuildingBlocks (>= 0.4.0)
- Cayaqui.MPS.Cqrs (>= 0.1.0)
- Microsoft.EntityFrameworkCore (>= 10.0.8)
- Microsoft.EntityFrameworkCore.Relational (>= 10.0.8)
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Diagnostics.HealthChecks.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Options (>= 10.0.8)
- Scrutor (>= 7.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
0.5.1 — FIX (SQL Server): Outbox ahora funciona en SQL Server / Azure SQL. OutboxMessageConfiguration era Postgres-only (forzaba HasColumnType("jsonb") → fallaba el CREATE TABLE en SQL Server). Ahora es provider-agnóstico: nuevo ctor OutboxMessageConfiguration(string? schema = null, string? jsonColumnType = null) — el tipo de columna del payload se inyecta (null = default del provider). Nuevo IOutboxDialect.JsonColumnType (Postgres "jsonb", SqlServer "nvarchar(max)") para mantener el mapeo consistente con el dialect runtime. El ctor sin parámetros sigue compilando (consumidores PG que quieran jsonb deben pasarlo explícito: el default pasa a neutral). Sin cambios de runtime SQL (PendingSql/PurgeSql intactos). 0.5.0 — BREAKING: public namespace MPS.BuildingBlocks.EntityFrameworkCore.* (folder-matched, ya NO MPS.SharedKernel.*). CQRS: TransactionHandlerDecorator (frontera UoW, execution-strategy para Azure SQL, rollback en excepción y en Result de fallo, NO despacha — el outbox interceptor lo hace), AddMpsCqrs<TDbContext> (pipeline de decorators logging→validation→transaction), AddMpsPersistence (audit+domain-event+UTC interceptors), UtcDateTimeInterceptor. Outbox provider-agnóstico (IOutboxDialect: Postgres FOR UPDATE SKIP LOCKED + SqlServer UPDLOCK/READPAST en ReadPending y Purge). 0.4.0 — namespace MPS.SharedKernel.* (shim). 0.3.0/0.2.0 — Outbox rico (OutboxMessage con EventId/EventType/retry/permanent-fail, EfOutboxStore con FOR UPDATE SKIP LOCKED + IAsyncDisposable, OutboxRedispatchHostedService con backoff + deserialización por type name, OutboxPurgeHostedService, OutboxHealthCheck multi-store). DomainEventDispatchInterceptor persiste eventos al outbox en la misma transacción. ScopedQueryHandler/ScopedCommandHandler (ctor IServiceScopeFactory, ExecuteAsync(query,db,sp,ct) → Result<T>). DI: AddDomainEventDispatcher, AddOutboxRedispatchService(IConfiguration), AddModuleOutbox<T>(moduleName), AddDomainEventHandlersFromAssembly. 0.1.0 — initial simplified release.