mediator
Skill1 starsChanged 6 days agoMITView on GitHub
How source-generated Mediator carries requests from the presentation layer to Application handlers - registration and lifetime, IRequest and IRequestHandler, ValueTask, pipeline behaviours and their order, and why it isn't MediatR. Use when adding or changing a pipeline behaviour, sending a request, or when a handler isn't found.
3 other projects use a version of this.
Adopted by
Most recently taken up by
- bas1l/claude-skillstheir own version, first seen Nov 3, 2026
- catduckgnaf/claude-skillstheir own version, first seen Aug 3, 2026
- Calvin646590/agent-teamtheir own version, first seen May 26, 2026
Other versions3 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 3
- bas1l/claude-skills★ 0same name
- Calvin646590/agent-team★ 0same name
- catduckgnaf/claude-skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository40 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-a-use-caseSkill
- api-conventionsSkill
- branches-and-pull-requestsSkill
- cancellationSkill
- ci-for-your-solutionSkill
- ci-pipelineSkill
- clean-architecture-layersSkill
- configuration-and-environmentsSkill
- coverageSkill
- csharp-house-styleSkill
- data-access-ef-coreSkill
- database-migrationsSkill
- docker-and-composeSkill
- docs-and-voiceSkill
- errors-and-exceptionsSkill
- expose-a-use-caseSkill
- family-syncSkill
- health-checksSkill
- integration-testsSkill
- json-serializationSkill
- mapping-with-mapperlySkill
- mcp-inspectorSkill
- optional-token-authSkill
- packages-and-dependenciesSkill
- pagingSkill
- presentation-integration-testsSkill
- releasesSkill
- sample-dataSkill
- security-findingsSkill
- serilogSkill
- telemetrySkill
- template-authoringSkill
- test-designSkill
- time-providerSkill
- unit-testsSkill
- validationSkill
- writing-a-skillSkill
- xml-docs-and-openapiSkill
The file
We split this skill into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 22
Every request uses IRequest<TResponse>.
- Very specific: line 31
Test the behaviour on its own with a fake next delegate (unit-tests), including the case where it stops the request.
- Distinctive: line 59
Add MediatR, or any package with a commercial licence.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Mediator
The rule
Requests travel from the presentation layer to Application through Mediator (Mediator.Abstractions in Application, Mediator.SourceGenerator in Presentation). It's MIT licensed and generates its dispatch code at build time, so there's no reflection scanning at startup.
| Piece | Where | How |
| Request | src/Application/<Feature>/<Commands or Queries>/<UseCase>/ | A class implementing IRequest<TResponse> |
| Handler | Beside the request | IRequestHandler<TRequest, TResponse>, returns ValueTask<TResponse> |
| Behaviours | src/Application/Common/Behaviours/ | IPipelineBehavior<TMessage, TResponse>, registered as open generics in src/Application/DependencyInjection.cs |
| Registration | The presentation layer's startup | AddMediator with ServiceLifetime.Scoped, so handlers share the request's scoped DbContext |
| Sending | Presentation only | ISender.Send(request, cancellationToken) |
Every request uses IRequest<TResponse>. Mediator also offers ICommand and IQuery markers; we don't use them, because nothing yet needs a behaviour that applies to only one kind.
Behaviours run in the order they're registered. The first one registered is the outermost, so it runs first on the way in and last on the way out. LoggingBehaviour is registered first, so it times and logs everything inside it, validation failures included (serilog), and its span wraps the use case (telemetry). ValidationBehaviour comes next, so invalid requests never reach a handler.
Steps
- A new use case needs no registration. The generator finds the request and its handler when the solution builds (
add-a-use-case). - To add a behaviour, create
<Name>Behaviour<TMessage, TResponse>insrc/Application/Common/Behaviours/, constrained towhere TMessage : IMessage, and callnext(message, cancellationToken)exactly once. - Register it in
AddApplicationwithservices.AddScoped(typeof(IPipelineBehavior<,>), typeof(<Name>Behaviour<,>)), in the position that gives the order you want. - Test the behaviour on its own with a fake
nextdelegate (unit-tests), including the case where it stops the request. - Send requests only from the presentation layer, always passing the cancellation token (
cancellation).
Example
// src/Application/DependencyInjection.cs
_ = services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly(), ServiceLifetime.Transient);
_ = services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingBehaviour<,>));
_ = services.AddScoped(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>));// src/Application/Common/Behaviours/ValidationBehaviour.cs
public class ValidationBehaviour<TMessage, TResponse>(IEnumerable<IValidator<TMessage>> validators) : IPipelineBehavior<TMessage, TResponse>
where TMessage : IMessage
{
public async ValueTask<TResponse> Handle(TMessage message, MessageHandlerDelegate<TMessage, TResponse> next, CancellationToken cancellationToken)
{
// ... throws ValidationException when any validator fails
return await next(message, cancellationToken);
}
}Don't
- Add MediatR, or any package with a commercial licence. Mediator is the one we use.
- Send a request from inside a handler. Call the repository, or move the shared logic into the Application layer.
- Register
AddMediatorwith the default singleton lifetime. Handlers would hold oneDbContextfor the life of the app. - Return
Taskfrom a handler. The interface wantsValueTask. - Await a
ValueTasktwice, or keep it to await later.
Check
dotnet build # the generator reports missing or duplicate handlers
dotnet test tests/Application.Tests.UnitDoes it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

