PouryaKit.Domain
The plain types your aggregates are made of.
The plain types your aggregates are made of. An aggregate derives from AggregateRoot<TId> and is keyed by a typed ID, a behaviour that can fail checks its business rules and returns a Result with a value or an Error for an expected business failure, and what happened is raised as a Domain Event. The package has no dependencies, so it adds nothing to your domain but these types.
Install
dotnet add package PouryaKit.Domain --prereleaseWhen to use it
- You are writing an aggregate, an entity or the typed ID that keys it.
- A business rule decides whether a change may happen.
- Something in the domain happened that other code reacts to: a Domain Event.
- You are declaring the Errors of a Business Area.
- A business rule compares with the current time, or a test fixes the time a Domain Event records.
A Module's handlers return these types through PouryaKit.Cqrs, and PouryaKit.Persistence.Postgres stores its aggregates.
Quick start
There is nothing to register. A behaviour checks its rule, returns an Error for a business failure and raises a Domain Event on success, as the Proving Sample's Product does:
public static Result<Product> Create(
ProductId id,
CategoryId categoryId,
string name,
string tenant
)
{
ArgumentNullException.ThrowIfNull(id);
ArgumentNullException.ThrowIfNull(categoryId);
ArgumentException.ThrowIfNullOrWhiteSpace(tenant);
if (string.IsNullOrWhiteSpace(name))
{
return ProductErrors.NameRequired;
}
var product = new Product
{
Id = id,
Tenant = tenant,
CategoryId = categoryId,
Name = name.Trim(),
};
product.Raise(new ProductCreatedDomainEvent(id, categoryId, product.Name));
return product;
}What you get
ResultandError: a value on success, one or more named Errors on failure.- Typed IDs: one sealed record per aggregate, over a
Guid,long,intorstring, so the compiler refuses one aggregate's ID where another's belongs. - Domain Events raised by the aggregate, for the Unit of Work to run.
- Opt-in markers for audit and soft delete, whose fields the Unit of Work sets, and for a tenant's aggregates.
DomainClock, the time a Domain Event records, which a test can fix. A business rule that compares with now takes the time as a parameter.
Return an Error for anything an Actor can cause, such as a missing name. Exceptions are for bugs and infrastructure. Never set an aggregate's Version or clear its Domain Events: the Unit of Work owns both.