Part of DKNet.EfCore.Events. Connect entity event queues to one or more IEventPublisher implementations through the save hook.
Use the console-project setup in the Quick Start, then replace Program.cs with this example.
using Microsoft.EntityFrameworkCore;
using DKNet.EfCore.Hooks;
using Microsoft.Extensions.DependencyInjection;
using var connection = new Microsoft.Data.Sqlite.SqliteConnection("Data Source=:memory:");
connection.Open();
var services = new Microsoft.Extensions.DependencyInjection.ServiceCollection();
services.AddLogging();
services.AddDbContextWithHook<DemoDb>(o => o.UseSqlite(connection));
services.AddEventPublisher<DemoDb, ConsolePublisher>();
using var provider = services.BuildServiceProvider();
using var scope = provider.CreateScope();
await using var db = scope.ServiceProvider.GetRequiredService<DemoDb>();
await db.Database.EnsureCreatedAsync();
var item = new Item();
item.Announce();
db.Add(item);
await db.SaveChangesAsync();
public sealed class DemoDb(DbContextOptions<DemoDb> options) : DbContext(options)
{
public DbSet<Item> Items => Set<Item>();
}
public sealed class Item : DKNet.EfCore.Abstractions.Entities.Entity<int>
{
public string Name { get; set; } = "Coffee";
public void Announce() => AddEvent(new ItemCreated(Name));
}
public sealed record ItemCreated(string Name);
public sealed class ConsolePublisher : DKNet.EfCore.Abstractions.Events.DefaultEventPublisher
{
public override Task PublishAsync(object value, CancellationToken cancellationToken = default)
{
Console.WriteLine(value); // ItemCreated { Name = Coffee }
return Task.CompletedTask;
}
}
Only entities in the changed-entry snapshot participate in manual queue dispatch. Object events pass through; queued event types map from the live entity. EventContext de-duplicates each entity queue using object equality and stamps sourceType on manually queued IEventItem payloads.
| Registration | Lifetime / default | Effect |
|---|---|---|
AddEventPublisher<TDbContext, TPublisher>() |
Scoped publisher | Add publisher and EventHook for this context. |
AddDbContextWithHook<TDbContext>() |
Scoped context by default | Install async-save interceptor. |
MapsterMapper.IMapper |
host-supplied, first resolved | Needed for queued event types and declared events. |
ILogger<EventHook> |
optional | Information per after-save pass and errors for publisher failures. |
Abstractions defines the entity queues and publisher contracts. Hooks invokes EventHook around the context save, and the host publisher implementation owns transport or external side effects.