What is PouryaKit
A reusable .NET 10 foundation for modular monoliths, in which Feature code holds only business behaviour.
What it is
PouryaKit is a set of NuGet packages and dotnet new templates for applications built as a Host of Modules on .NET 10 and PostgreSQL. Each Module is a business boundary that owns its data, its rules and its public Contracts.
Inside a Module, your code is Features. A Feature supplies the aggregate, the command or query, its validator and handler, its data access and its endpoint. The Kit runs everything around it: it dispatches the Operation, validates it, owns its single commit in the Unit of Work, runs its reactions and delivers its Integration Events and Snapshots to other Modules.
The packages are grouped into Capabilities: one or a few packages each, such as Messaging, Web or File storage. A Host references the ones it uses.
The packages are MIT-licensed. The Kit's source repository is private, so a package's nuget.org page has no working source link.
Feature code never commits
The Unit of Work writes the Outbox, saves and commits, and sends what it wrote only after the commit. A handler returns its Result and leaves all of it to the Unit of Work; the structure tests refuse code that saves or commits by itself.
When to use it
Start a new .NET 10 application on the Kit when its business code should be split into Modules that each own their data, and you want the commit, the Outbox, the deliveries between Modules and the checks on your composition handled for you. One Module is a fine start: the monolith template grows into a modular monolith when a second Module arrives, and a Module can later run as a service of its own.
A Feature
The handler that renames a product in the Proving Sample. It returns a Result: an Error when the product does not exist, or what the rename returned. Nothing in it saves.
internal sealed class RenameProductCommandHandler(IRepository<Product, ProductId> products)
: CommandHandler<RenameProductCommand>
{
public override async Task<Result> Handle(
RenameProductCommand command,
CancellationToken cancellationToken
)
{
var product = await products.FindAsync(new ProductId(command.ProductId), cancellationToken);
return product is null ? ProductErrors.NotFound : product.Rename(command.Name);
}
}Start a project
Check the prerequisites
The .NET 10 SDK and Docker; Prerequisites lists what each step needs.
Install the templates
dotnet new install PouryaKit.Templates@0.1.0-preview.2Run your first Host
Your first Host generates a solution, starts PostgreSQL, migrates, and calls the running Host.
What the Kit guarantees
The first rule is a structure rule: the Kit's own tests are not published, so a project writes its own structure tests to hold its code to it.
| Rule | Stated in |
|---|---|
| Feature code never saves, commits or touches the Outbox | Structure tests |
| A Notification Handler runs only after the commit | Persistence guarantees |
| Every failure answers one problem response | Problem responses |
| There is no default Actor | The Operation Context |
| In a tenant-scoped Module, EF Core reads and saves keep to the Operation's tenant; plain SQL states it itself | Multi-tenancy guarantees |
| A declaration that cannot work fails the Host when it is built | The Host's checks |
Failure messages
The Kit refuses a mistake as early as it can, and its messages name what to change.