ME

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.zip

Installs 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.
436 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

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

You give it
Service registrations, message requests, diagnostic configurations
You get back
Configured MediatorLite services, dispatched messages, diagnostic events

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.FluentValidation package. The in-house ValidationBehavior / DataAnnotationsValidator referenced 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 ThrowingMediator diagnostic fallback and how the generated mediator supersedes it.
  • Adjusting ValidationBehavior ordering semantics or DataAnnotationsValidator behavior.
  • Renaming or adding OpenTelemetry tags / activity names in MediatorDiagnostics.

Project location & entry points

  • MediatorLite.csproj — targets net10.0, references Microsoft.Extensions.DependencyInjection.Abstractions 9.0.0 and Microsoft.Extensions.Logging.Abstractions 9.0.0, and project-references MediatorLite.Abstractions.csproj.
  • The IMediator implementation is generated (SourceGeneratedMediator in the MediatorLite.Generated namespace) — it is not a file in this project. See the mediatorlite-source-generation skill.
  • ServiceCollectionExtensions.csAddMediatorLite() entry point.
  • ThrowingMediator.cs — diagnostic fallback IMediator that throws if no generator ran.
  • PipelineBehaviorTypeResolver.csdeleted (v1 runtime behavior-type resolution; the generated mediator unrolls behaviors at compile time, so nothing needs it).
  • MediatorDiagnostics.csMediatorActivitySource (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>(...) returning ValueTask<TConcrete>, converted to ValueTask<TResponse> via an identity-guarded System.Runtime.CompilerServices.Unsafe.As (the typeof guard JIT-folds to a constant). Value-type responses stay typed — there is no Task<object> and no (TResponse) unbox. v1 boxed; v2 eliminated it.
  • SlowCast is the only fallback, for covariant IRequest<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's ValueTask directly — no async state machine.
  • PublishAsync has a matching switch over the notification's runtime type; Publish_<SafeType> methods return ValueTask. The default: arm returns default (no-op) when no handler is registered. Because it matches the runtime type, base/interface-typed publishes dispatch correctly (v1's typeof(TNotification) dictionary lookup silently no-oped for those).
  • The case null: arm throws ArgumentNullException before 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 ThrowingMediator via TryAddScoped<IMediator, ...>. The real mediator is registered by the generated AddGeneratedHandlers() with plain AddScoped<IMediator, SourceGeneratedMediator>().
  • Because the generated registration is unconditional AddScoped and the container resolves the last IMediator descriptor, the generated mediator always wins. The TryAdd only takes effect when AddGeneratedHandlers() never ran — turning a missing generator into a clear InvalidOperationException instead 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 longer Transient.

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.

SkillInstallsUpdatedSafetyDifficulty
mediatorlite-core (this skill)02moNo flagsAdvanced
dotnet-backend-patterns75moNo flagsAdvanced
azure-servicebus-dotnet33moReviewIntermediate
azure-eventgrid-dotnet13moReviewIntermediate

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.

722

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".

316

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".

11

websocket-integration

sunyonghuan

通过 WebSocket 连接 Cortana AI 对话服务。编写 C# 客户端代码,实现发送消息、接收流式回复、附件传输、系统事件监听。触发关键词:WebSocket、WS 连接、远程对话、流式回复、AI 接入、实时通信。

00

azure-ai-voicelive-dotnet

wegonbeok45

Azure AI Voice Live SDK for .NET. Build real-time voice AI applications with bidirectional WebSocket communication.

00

cqrs-feature

FlorianDrevet

Use when touching backend feature slices in the .NET CQRS stack of this repository.

00

Search skills

Search the agent skills registry