CQRS interface reference for FSH. This project uses the Mediator source generator, NOT MediatR. Reference when implementing commands, queries, and handlers.
68
82%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
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) |
3f2959e
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.