DKNet is a suite of independent .NET 10 NuGet packages for building enterprise applications around
Domain-Driven Design and Onion Architecture. There is no framework to adopt wholesale and no single
AddDKNet() call: each package registers itself and can be used on its own, so you pull in only what a given
DbContext, API, or worker actually needs.
28 packages are published to NuGet. One more, Aspire.Hosting.ServiceBus, is source-only in this repository
(<IsPackable>false</IsPackable>) and documented anyway — it is an Aspire shared project you reference from an
AppHost directly. DKNet.EfCore.Repos and DKNet.EfCore.Repos.Abstractions, the older generic-repository
packages, were removed outright; see Migrating-Repos-To-Specifications
if you are upgrading off them.
dknet-skills) — install with npx skills add baoduy/DKNet or claude plugin install dknet-skills@dknet so your coding agent knows every packageSorted by the problem you have, not by namespace. Follow the link for the full API and gotchas.
| I need to… | Package |
|---|---|
| Give entities identity, audit fields, and a domain-event queue | DKNet.EfCore.Abstractions |
Have EF Core discover my IEntityTypeConfiguration<T> classes, apply global filters, seed data, use GUID v7 keys or SQL sequences |
DKNet.EfCore.Extensions |
| Query and persist without hand-rolling a repository per entity | DKNet.EfCore.Specifications |
| Build a search/filter predicate whose criteria are only known at runtime | DKNet.EfCore.Specifications — Dynamic Predicate Builder |
Run my own code before and after every SaveChanges |
DKNet.EfCore.Hooks |
| Let a domain method raise an event that other code reacts to after the write commits | DKNet.EfCore.Events |
| Record who changed which field, with sensitive values redacted | DKNet.EfCore.AuditLogs |
| Stop one tenant or owner from reading another’s rows | DKNet.EfCore.DataAuthorization |
| Encrypt a column without changing the queries that read it | DKNet.EfCore.Encryption |
| Stop hand-writing DTOs that mirror entities | DKNet.EfCore.DtoGenerator |
| Check for or create a table at runtime, whatever the relational provider | DKNet.EfCore.Relational.Helpers |
Separate commands from queries and stop calling SaveChangesAsync in handlers |
DKNet.SlimBus.Extensions |
| Generate CRUD requests, handlers, and endpoints from an attributed entity member | DKNet.SlimBus.Generators |
Map minimal-API endpoint groups by convention and turn a Result into ProblemDetails |
DKNet.AspCore.Extensions |
Make a POST/PUT/PATCH safe for a client to retry |
DKNet.AspCore.Idempotency on its own for local development, plus one store package for deployed traffic |
| Run a job exactly once at start-up, before traffic arrives | DKNet.AspCore.Tasks |
| Store files without binding the application to one cloud | DKNet.Svc.BlobStorage.Abstractions plus one adapter |
| Encrypt, sign, or hash a value in ordinary application code | DKNet.Svc.Encryption |
| Render Markdown or HTML to a PDF file | DKNet.Svc.PdfGenerators |
| Fill bracketed tokens in a template string from an object or a dictionary | DKNet.Svc.Transformation |
| Generate a password, token, or other secret | DKNet.RandomCreator |
Scan assemblies for types, or reach for a string/enum/DateTime/reflection helper |
DKNet.Fw.Extensions |
| Give a local Aspire AppHost its own Azure Service Bus emulator | Aspire.Hosting.ServiceBus (source-only) |
Foundation utilities that sit at the bottom of the dependency graph and pull in nothing else from DKNet.
TypeExtractors)Entity base classes, the specification pattern, and the SaveChanges interceptor pipeline everything else hangs off.
DKNet.EfCore.* package builds on: entity base classes, domain-event contracts, and the attributes that steer audit, sequence, and mapping behaviourSnapshotContext the save hooks are built onIRepositorySpec, plus a runtime dynamic predicate builder. The current, supported way to query and persistSaveChanges interceptor pipeline: one shared interceptor per DbContext type plus a pair of interfaces you implementSaveChanges, so a domain method never references a publisher or a busSaveChanges-time owner stamping on writesstring properties, applied at the database boundary via a standard ValueConverterDbContext extension methods for relational bookkeeping EF Core does not expose: table creation, connection access, table-name resolution, and table-existence checksSlimMessageBus integration: CQRS contracts, automatic save, and the CRUD source generator.
SaveChanges after a successful write, and domain events forwarded onto the bus[CrudCreate]/[CrudUpdate]/[CrudAction]-attributed entity membersApplication-level services with no dependency on the EF Core packages.
IBlobService contract and shared model typesAzure.Storage.BlobsStart-up orchestration, minimal-API glue, and idempotency for web and API workloads.
FluentResults-to-IResult conversionIBackgroundTask, register it, and one BackgroundService runs every registered task once when the host startsIEndpointFilter that recognises a client-supplied idempotency key, blocks the same operation from running twice, and replays or rejects the retrySET NX reservation and native key expiry, with no schema or migrationsInfrastructure orchestration helpers for .NET Aspire AppHost projects.
<IsPackable>false</IsPackable>, so reference the project from your AppHost rather than a NuGet packageEvery ring of the onion is a separate package, and every dependency points inward. The Architecture Guide walks the same picture in detail, adds the package dependency graph, and traces a request and a domain event end to end.
ProjectReference entries in src/.DKNet.EfCore.Abstractions is the only package a domain model has to see.IRepositorySpec serves every entity type; the entity comes from the specification passed to each call.Corrections and additions are welcome. Open an issue describing the problem, or send a pull request that follows the structure and voice of the surrounding pages — the canonical page structure is the Package Documentation Template; see also the Contributing Guide.
Every claim on these pages should be traceable to src/, a test, or a config file. If you find one that
is not, that is a bug worth reporting in the DKNet repository.