mediatorlite-core
Core runtime logic for MediatorLite, including DI extensions and high-performance dispatch diagnostics.
Install
mkdir -p .claude/skills/mediatorlite-core && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/12309" && unzip -o skill.zip -d .claude/skills/mediatorlite-core && rm skill.zipInstalls to .claude/skills/mediatorlite-core
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Runtime implementation for MediatorLite -- AddMediatorLite() DI extension, the ThrowingMediator diagnostic fallback, the generated SourceGeneratedMediator (implements IMediator via ValueTask typed-switch dispatch), MediatorDiagnostics (ActivitySource + DiagnosticListener), and the Validation subsystem (ValidationBehavior + DataAnnotationsValidator). Use when touching dispatch, DI registration, diagnostics, or the validation runtime.Key capabilities
- →Register MediatorLite services using `AddMediatorLite()`
- →Understand the `ThrowingMediator` diagnostic fallback
- →Adjust `ValidationBehavior` ordering semantics
- →Rename or add OpenTelemetry tags in `MediatorDiagnostics`
- →Dispatch messages without reflection using compile-time type-pattern switch
- →Handle `ValueTask` typed-switch dispatch
How it works
The skill provides the runtime implementation for MediatorLite, including DI extensions and diagnostic sources. It uses a source-generated mediator for dispatch via a compile-time C# type-pattern switch, avoiding reflection.
Inputs & outputs
When to use mediatorlite-core
- →Setting up MediatorLite
- →Debugging dispatch performance
- →Configuring DI services
- →Implementing validation behaviors
About this skill
MediatorLite (Core Runtime)
⚠️ Partially STALE. Validation moved to FluentValidation in the opt-in
MediatorLite.FluentValidationpackage. The in-houseValidationBehavior/DataAnnotationsValidatorreferenced here were removed from core — core has no validation subsystem. See mediatorlite-validation, .claude/rules/50-validation.md, docs/validation.md.
Purpose
MediatorLite (project name, not the solution) is the runtime library consumers reference. It does not contain a hand-written IMediator implementation — the real IMediator is the generated SourceGeneratedMediator emitted by MediatorLite.SourceGeneration. This project contains the DI extension (AddMediatorLite()), the ThrowingMediator diagnostic fallback, diagnostic sources, and the validation runtime. The dispatch path contains zero reflection at call time — the generated mediator dispatches via a compile-time C# type-pattern switch. Logging and tracing are emitted inline by the generator, not by this project.
When to use
- Adding or tweaking
AddMediatorLite()registrations (for example, registering additional runtime services). - Understanding the
ThrowingMediatordiagnostic fallback and how the generated mediator supersedes it. - Adjusting
ValidationBehaviorordering semantics orDataAnnotationsValidatorbehavior. - Renaming or adding OpenTelemetry tags / activity names in
MediatorDiagnostics.
Project location & entry points
- MediatorLite.csproj — targets
net10.0, referencesMicrosoft.Extensions.DependencyInjection.Abstractions 9.0.0andMicrosoft.Extensions.Logging.Abstractions 9.0.0, and project-references MediatorLite.Abstractions.csproj. - The
IMediatorimplementation is generated (SourceGeneratedMediatorin theMediatorLite.Generatednamespace) — it is not a file in this project. See the mediatorlite-source-generation skill. - ServiceCollectionExtensions.cs —
AddMediatorLite()entry point. - ThrowingMediator.cs — diagnostic fallback
IMediatorthat throws if no generator ran. — deleted (v1 runtime behavior-type resolution; the generated mediator unrolls behaviors at compile time, so nothing needs it).PipelineBehaviorTypeResolver.cs- MediatorDiagnostics.cs —
MediatorActivitySource(OpenTelemetry) +DiagnosticListener. - ValidationBehavior.cs — generic pipeline behavior that runs registered
IValidator<T>s. - DataAnnotationsValidator.cs — built-in validator using
System.ComponentModel.DataAnnotations.
Core types / API surface
The generated SourceGeneratedMediator — typed-switch dispatch
There is no hand-written Mediator.cs in v2. The generator emits SourceGeneratedMediator : global::MediatorLite.IMediator (namespace MediatorLite.Generated) which holds a single IServiceProvider _sp field and dispatches via a compile-time C# type-pattern switch:
// Emitted shape (MediatorLite.Generated.SourceGeneratedMediator)
public sealed class SourceGeneratedMediator : global::MediatorLite.IMediator
{
private readonly IServiceProvider _sp;
public SourceGeneratedMediator(IServiceProvider serviceProvider) => _sp = serviceProvider;
public ValueTask<TResponse> SendAsync<TResponse>(IRequest<TResponse> request, CancellationToken ct = default)
{
switch (request)
{
case MyQuery r:
{
var vt = Send_MyQuery(r, ct); // ValueTask<MyResult>
if (typeof(TResponse) == typeof(MyResult))
return Unsafe.As<ValueTask<MyResult>, ValueTask<TResponse>>(ref vt);
return SlowCast<MyResult, TResponse>(vt); // covariant IRequest<out T> fallback
}
case null: throw new ArgumentNullException(nameof(request));
default: throw new InvalidOperationException(/* no handler */);
}
}
// ...PublishAsync switch + Send_<Type>/Publish_<Type> methods using _sp...
}
Key invariants:
- No boxing. Each arm calls a fully typed
Send_<SafeType>(...)returningValueTask<TConcrete>, converted toValueTask<TResponse>via an identity-guardedSystem.Runtime.CompilerServices.Unsafe.As(thetypeofguard JIT-folds to a constant). Value-type responses stay typed — there is noTask<object>and no(TResponse)unbox. v1 boxed; v2 eliminated it. SlowCastis the only fallback, for covariantIRequest<out T>dispatch (reference cast, no value-type boxing).Send_<SafeType>per-request methods are instance methods on_sp. A zero-behavior request with diagnostics disabled returns the handler'sValueTaskdirectly — no async state machine.PublishAsynchas a matching switch over the notification's runtime type;Publish_<SafeType>methods returnValueTask. Thedefault:arm returnsdefault(no-op) when no handler is registered. Because it matches the runtime type, base/interface-typed publishes dispatch correctly (v1'stypeof(TNotification)dictionary lookup silently no-oped for those).- The
case null:arm throwsArgumentNullExceptionbefore any handler resolution.
AddMediatorLite() — DI entry point
public static IServiceCollection AddMediatorLite(this IServiceCollection services)
{
// TryAdd keeps this order-independent with AddGeneratedHandlers(): the generated
// registration uses plain AddScoped, and the container resolves the last IMediator
// descriptor, so the generated mediator wins regardless of call order.
services.TryAddScoped<IMediator, ThrowingMediator>();
return services;
}
AddMediatorLite() is now an optional diagnostic fallback:
- It registers
ThrowingMediatorviaTryAddScoped<IMediator, ...>. The real mediator is registered by the generatedAddGeneratedHandlers()with plainAddScoped<IMediator, SourceGeneratedMediator>(). - Because the generated registration is unconditional
AddScopedand the container resolves the lastIMediatordescriptor, the generated mediator always wins. TheTryAddonly takes effect whenAddGeneratedHandlers()never ran — turning a missing generator into a clearInvalidOperationExceptioninstead of a resolution failure. - Call order of the two methods no longer matters. The mediator is Scoped (the generated mediator captures the resolving scope's
IServiceProvider; resolved from the root provider it behaves like a singleton). It is no longerTransient.
AddMediatorLite() takes no arguments. There is no MediatorOptions — v2 removed src/MediatorLite/Configuration/MediatorOptions.cs (see git status). All configuration is compile-time via attributes.
ThrowingMediator — diagnostic fallback
internal sealed class ThrowingMediator : IMediator
{
private const string Message =
"No source-generated mediator is registered. Reference the MediatorLite.SourceGeneration " +
"analyzer package from the assembly that contains your handlers and call " +
"services.AddGeneratedHandlers() so the generated mediator replaces this fallback.";
public ValueTask<TResponse> SendAsync<TResponse>(
IRequest<TResponse> request,
CancellationToken cancellationToken = default)
=> throw new InvalidOperationException(Message);
public ValueTask PublishAsync<TNotification>(
TNotification notification,
CancellationToken cancellationToken = default)
where TNotification : INotification
=> throw new InvalidOperationException(Message);
}
This type is registered only by AddMediatorLite() via TryAddScoped. When AddGeneratedHandlers() runs (the normal case), the generated SourceGeneratedMediator is registered after it and wins resolution, so ThrowingMediator never dispatches. If the generator never ran, every dispatch throws the guidance message above.
PipelineBehaviorTypeResolver — removed
This v1 helper (open- vs closed-behavior interface resolution for runtime registration) was deleted: the generated mediator unrolls behaviors itself at compile time, so nothing on the v2 dispatch or registration path needs runtime behavior-type resolution. Do not reintroduce it — behavior discovery/expansion belongs to the source generator (ExpandBehaviors in HandlerDiscoveryGenerator.cs).
MediatorActivitySource + MediatorDiagnostics
The generator emits Activity? starts with these constants; consumers subscribe via OpenTelemetry.
public static class MediatorActivitySource
{
/// <summary>
/// The name of the activity source.
/// </summary>
public const string SourceName = "MediatorLite";
/// <summary>
/// The version of the activity source.
/// </summary>
public const string Version = "1.0.0";
/// <summary>
/// The ActivitySource for MediatorLite tracing.
/// </summary>
public static readonly ActivitySource Source = new(SourceName, Version);
public static class ActivityNames
{
/// <summary>Send request activity name prefix.</summary>
public const string SendRequest = "MediatorLite.Send";
/// <summary>Publish notification activity
---
*Content truncated.*
When not to use it
- →When the `IMediator` implementation is hand-written
- →When reintroducing runtime behavior-type resolution
- →When reintroducing `MediatorOptions.cs`
Limitations
- →Validation subsystem moved to `MediatorLite.FluentValidation`
- →Does not contain a hand-written `IMediator` implementation
- →Does not reintroduce `PipelineBehaviorTypeResolver.cs`
How it compares
This skill implements message dispatching without reflection using compile-time type switching, offering a performance advantage over runtime reflection-based dispatchers.
Compared to similar skills
mediatorlite-core side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| mediatorlite-core (this skill) | 0 | 2mo | No flags | Advanced |
| dotnet-backend-patterns | 7 | 5mo | No flags | Advanced |
| azure-servicebus-dotnet | 3 | 3mo | Review | Intermediate |
| azure-eventgrid-dotnet | 1 | 3mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
dotnet-backend-patterns
wshobson
Master C#/.NET backend development patterns for building robust APIs, MCP servers, and enterprise applications. Covers async/await, dependency injection, Entity Framework Core, Dapper, configuration, caching, and testing with xUnit. Use when developing .NET backends, reviewing C# code, or designing API architectures.
azure-servicebus-dotnet
microsoft
Azure Service Bus SDK for .NET. Enterprise messaging with queues, topics, subscriptions, and sessions. Use for reliable message delivery, pub/sub patterns, dead letter handling, and background processing. Triggers: "Service Bus", "ServiceBusClient", "ServiceBusSender", "ServiceBusReceiver", "ServiceBusProcessor", "message queue", "pub/sub .NET", "dead letter queue".
azure-eventgrid-dotnet
microsoft
Azure Event Grid SDK for .NET. Client library for publishing and consuming events with Azure Event Grid. Use for event-driven architectures, pub/sub messaging, CloudEvents, and EventGridEvents. Triggers: "Event Grid", "EventGridPublisherClient", "CloudEvent", "EventGridEvent", "publish events .NET", "event-driven", "pub/sub".
websocket-integration
sunyonghuan
通过 WebSocket 连接 Cortana AI 对话服务。编写 C# 客户端代码,实现发送消息、接收流式回复、附件传输、系统事件监听。触发关键词:WebSocket、WS 连接、远程对话、流式回复、AI 接入、实时通信。
azure-ai-voicelive-dotnet
wegonbeok45
Azure AI Voice Live SDK for .NET. Build real-time voice AI applications with bidirectional WebSocket communication.
cqrs-feature
FlorianDrevet
Use when touching backend feature slices in the .NET CQRS stack of this repository.