CQRS interface reference for FSH. This project uses the Mediator source generator, NOT MediatR. Reference when implementing commands, queries, and handlers.
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
⚠️ FSH uses the Mediator source-generator package (using Mediator;), NOT MediatR. Different
interfaces — MediatR types won't compile. The CQRS interfaces below are the library's own (no FSH wrapper).
| Purpose | ✅ Mediator (use) | ❌ MediatR (don't) |
|---|---|---|
| Command | ICommand<TResponse> | IRequest<TResponse> |
| Query | IQuery<TResponse> | IRequest<TResponse> |
| Command handler | ICommandHandler<TCommand, TResponse> | IRequestHandler<…> |
| Query handler | IQueryHandler<TQuery, TResponse> | IRequestHandler<…> |
| Notification / domain event | INotification (IDomainEvent : INotification) | INotification |
// Command/Query → the Contracts project (Modules.{X}.Contracts/v1/{Area}/)
public sealed record Create{Entity}Command(string Name) : ICommand<Guid>;
// Handler → the runtime project (Modules.{X}/Features/v1/{Area}/{Feature}/), public sealed
public sealed class Create{Entity}CommandHandler({X}DbContext db)
: ICommandHandler<Create{Entity}Command, Guid>
{
public async ValueTask<Guid> Handle(Create{Entity}Command command, CancellationToken cancellationToken)
{
// …
}
}Rules: handlers return ValueTask<T> (not Task<T>); parameter named command/query (not request);
public sealed; .ConfigureAwait(false) on awaits. Send via mediator.Send(command, ct) (the IMediator
interface name matches MediatR's — that part is fine).
The source generator only scans assemblies listed in o.Assemblies, and that list exists in two host
files. A new module needs two markers (a Contracts type and the module type) added to the Mediator
list plus an entry in the moduleAssemblies array — in both FSH.Starter.Api/Program.cs and
FSH.Starter.DbMigrator/Program.cs:
builder.Services.AddMediator(o =>
{
o.ServiceLifetime = ServiceLifetime.Scoped;
o.Assemblies = [
/* … */
typeof(FSH.Modules.{X}.Contracts.{X}ContractsMarker), // Contracts assembly
typeof(FSH.Modules.{X}.{X}Module)]; // runtime assembly
});See add-module for the full procedure.
| Symptom | Cause → fix |
|---|---|
IRequest<T> / IRequestHandler<,> not found | MediatR interface → use ICommand/IQuery + ICommandHandler/IQueryHandler |
Task<T> vs ValueTask<T> mismatch | Handler must return ValueTask<T> |
| Handler not invoked at runtime | Assembly missing from o.Assemblies (in one or both Program.cs files) |
fullstackhero/dotnet-starter-kit
a967537
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.