MediatorLite.SourceGeneration 1.0.13

dotnet add package MediatorLite.SourceGeneration --version 1.0.13
                    
NuGet\Install-Package MediatorLite.SourceGeneration -Version 1.0.13
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="MediatorLite.SourceGeneration" Version="1.0.13">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="MediatorLite.SourceGeneration" Version="1.0.13" />
                    
Directory.Packages.props
<PackageReference Include="MediatorLite.SourceGeneration">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add MediatorLite.SourceGeneration --version 1.0.13
                    
#r "nuget: MediatorLite.SourceGeneration, 1.0.13"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package MediatorLite.SourceGeneration@1.0.13
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=MediatorLite.SourceGeneration&version=1.0.13
                    
Install as a Cake Addin
#tool nuget:?package=MediatorLite.SourceGeneration&version=1.0.13
                    
Install as a Cake Tool

MediatorLite Icon MediatorLite.SourceGeneration

CI MediatorLite Version MediatorLite Downloads MediatorLite.SourceGeneration Version MediatorLite.SourceGeneration Downloads License: MIT .NET

Source generators for MediatorLite that enable compile-time handler discovery with zero runtime reflection.

Documentation: behl1anmol.github.io/MediatorLite

What is this?

MediatorLite.SourceGeneration is a Roslyn source generator that automatically discovers and registers handlers, behaviors, and validators at compile-time. This eliminates runtime reflection overhead and provides faster startup times and better performance.

Why use Source Generation?

  • Zero Runtime Reflection: Handler discovery happens at compile-time, not runtime
  • Faster Startup: No need to scan assemblies for handlers during application initialization
  • Better Performance: Direct method calls instead of reflection-based invocation
  • Compile-Time Safety: Errors are caught during compilation, not at runtime
  • Trimming-Friendly: Works with .NET's native AOT and assembly trimming

Installation

Install both packages together:

dotnet add package MediatorLite
dotnet add package MediatorLite.SourceGeneration

Usage

1. Register Services with Source Generation

The source generator automatically discovers all handlers, behaviors, and validators at compile time:

using MediatorLite.Generated;

services
    .AddGeneratedHandlers()   // Registers all handlers, behaviors, validators
    .AddMediatorLite();       // Registers the mediator

That's it! The source generator:

  • Discovers all IRequestHandler<,> implementations
  • Discovers all INotificationHandler<> implementations
  • Discovers all IPipelineBehavior<,> implementations
  • Discovers all IValidator<TRequest> implementations
  • Auto-registers DataAnnotationsValidator<T> for types with validation attributes
  • Registers everything with the DI container

To configure options:

services
    .AddGeneratedHandlers()
    .AddMediatorLite(options =>
    {
        options.EnableBuiltInLogging = true;
        options.EnableTracing = true;
        options.NotificationExecutionStrategy = NotificationExecutionStrategy.Parallel;
    });

2. Define Handlers

The source generator automatically discovers handlers - no attributes needed:

// Request handler - automatically discovered
public class GetUserQueryHandler : IRequestHandler<GetUserQuery, User>
{
    public async ValueTask<User> HandleAsync(
        GetUserQuery request,
        CancellationToken cancellationToken = default)
    {
        // Your logic here
    }
}

// Notification handler - automatically discovered
public class SendWelcomeEmailHandler : INotificationHandler<UserCreatedNotification>
{
    public async ValueTask HandleAsync(
        UserCreatedNotification notification,
        CancellationToken cancellationToken = default)
    {
        // Your logic here
    }
}

3. Build Your Project

The source generator runs during compilation and generates registration code automatically. You'll see the generated code in your IDE (under Dependencies → Analyzers → MediatorLite.SourceGeneration).

Features

Granular Registration

If you only need specific handler categories:

services
    .AddGeneratedRequestHandlers()        // Only request handlers
    .AddGeneratedNotificationHandlers()   // Only notification handlers
    .AddGeneratedBehaviors()              // Only pipeline behaviors
    .AddGeneratedValidators()             // Only validators
    .AddMediatorLite();

Excluding Types from Source Generation

Use [MediatorGeneration(Skip = true)] to exclude specific handlers:

[MediatorGeneration(Skip = true)]
public class TestOnlyHandler : IRequestHandler<TestQuery, string>
{
    // This handler will NOT be registered by AddGeneratedHandlers()
}

Configurable Handler Execution

Use attributes to control notification handler behavior:

// Control handler execution order
[NotificationHandlerOrder(1)]  // Execute first
public class FirstHandler : INotificationHandler<UserCreated>
{
    public async ValueTask HandleAsync(UserCreated notification, CancellationToken ct = default)
    {
        // Executes first
    }
}

[NotificationHandlerOrder(2)]  // Execute second
public class SecondHandler : INotificationHandler<UserCreated>
{
    public async ValueTask HandleAsync(UserCreated notification, CancellationToken ct = default)
    {
        // Executes second
    }
}

Override global notification execution strategy per notification:

[NotificationOptions(
    ExecutionStrategy = NotificationExecutionStrategy.Parallel,
    ErrorStrategy = NotificationErrorStrategy.ContinueAndAggregate)]
public record UserCreatedNotification(int UserId) : INotification;

Automatic Validation Support

The source generator automatically handles validation:

using System.ComponentModel.DataAnnotations;

public record CreateUserCommand : IRequest<int>
{
    [Required(ErrorMessage = "Name is required")]
    [StringLength(100, MinimumLength = 2)]
    public required string Name { get; init; }

    [Required]
    [EmailAddress(ErrorMessage = "Invalid email format")]
    public required string Email { get; init; }
}

// Source generator automatically:
// 1. Detects DataAnnotation attributes on CreateUserCommand
// 2. Registers DataAnnotationsValidator<CreateUserCommand>
// 3. Registers ValidationBehavior<CreateUserCommand, int> first in pipeline

Create custom validators:

public class CreateUserValidator : IValidator<CreateUserCommand>
{
    public async ValueTask<ValidationResult> ValidateAsync(
        CreateUserCommand request,
        CancellationToken cancellationToken = default)
    {
        var errors = new List<ValidationError>();

        // Custom validation logic
        if (await _userRepository.EmailExistsAsync(request.Email, cancellationToken))
        {
            errors.Add(new ValidationError(
                nameof(request.Email),
                "Email is already registered",
                request.Email));
        }

        return errors.Count > 0
            ? ValidationResult.Failure(errors)
            : ValidationResult.Success;
    }
}

// Automatically discovered and registered by AddGeneratedHandlers()

Pipeline Behaviors

Create behaviors for cross-cutting concerns:

[BehaviorOrder(1)]  // Execute first (optional)
public class LoggingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
    public async ValueTask<TResponse> HandleAsync(
        TRequest request,
        RequestHandlerDelegate<TResponse> next,
        CancellationToken cancellationToken = default)
    {
        _logger.LogInformation("Handling {RequestType}", typeof(TRequest).Name);
        var response = await next();
        _logger.LogInformation("Handled {RequestType}", typeof(TRequest).Name);
        return response;
    }
}

// Automatically discovered and registered by AddGeneratedHandlers()

Performance

Source generation provides significant performance improvements:

  • Faster handler resolution - Direct type mapping instead of reflection scanning
  • Faster startup - No assembly scanning during application initialization
  • Zero allocation for handler lookups with source-generated mediator
  • Native AOT compatible for maximum performance

Diagnostics

The source generator exposes counts for diagnostics:

using MediatorLite.Generated;

Console.WriteLine($"Request handlers: {MediatorLiteRegistration.RequestHandlerCount}");
Console.WriteLine($"Notification handlers: {MediatorLiteRegistration.NotificationHandlerCount}");
Console.WriteLine($"Behaviors: {MediatorLiteRegistration.BehaviorCount}");
Console.WriteLine($"Validators: {MediatorLiteRegistration.ValidatorCount}");

Requirements

  • .NET Standard 2.0+ (for the generator itself)
  • MediatorLite package (same version)
  • C# 9.0 or later recommended for best IDE experience

How It Works

The source generator:

  1. Scans your compilation for handler implementations during build
  2. Generates MediatorLiteRegistration class with extension methods
  3. Creates AddGeneratedHandlers(), AddGeneratedRequestHandlers(), etc.
  4. Generates type-safe registration code
  5. Integrates seamlessly with MediatorLite's runtime

All of this happens during build - no runtime scanning required!

Troubleshooting

Generator Not Running

If handlers aren't being discovered:

  1. Ensure both MediatorLite and MediatorLite.SourceGeneration packages are installed
  2. Clean and rebuild your solution (dotnet clean && dotnet build)
  3. Check that you're using AddGeneratedHandlers() from MediatorLite.Generated namespace
  4. Verify your handlers are in the same project or referenced projects

IDE Not Showing Generated Code

  • Restart your IDE after installing the package
  • In Visual Studio: Check Solution Explorer → Dependencies → Analyzers → MediatorLite.SourceGeneration
  • In Rider: Check Solution → Dependencies → Source Generators

Build Warnings

The generator may emit warnings for:

  • Duplicate handler registrations
  • Missing dependencies
  • Invalid attribute usage

These are informational and help catch configuration issues early.

Manual Registration (Without Source Generation)

If you prefer manual registration, you can skip the source generator package:

// Install only MediatorLite package
dotnet add package MediatorLite

// Register manually
services.AddTransient<IRequestHandler<GetUserQuery, User>, GetUserQueryHandler>();
services.AddTransient<INotificationHandler<UserCreated>, SendEmailHandler>();
services.AddMediatorLite();

Source Code

Full documentation is available at behl1anmol.github.io/MediatorLite.

Visit the MediatorLite repository for:

  • Full documentation
  • Source code
  • Examples and samples
  • Issue tracking

License

This package is part of MediatorLite and shares the same MIT license.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.13 84 3/30/2026
1.0.11 82 3/4/2026
1.0.10 79 3/4/2026
1.0.8 98 2/22/2026
1.0.7 93 2/22/2026
1.0.6 94 2/22/2026
1.0.5 94 2/22/2026
1.0.4 91 2/15/2026