Knara.SourceGenerators.DesignPatterns.Mediator 1.1.0

dotnet add package Knara.SourceGenerators.DesignPatterns.Mediator --version 1.1.0
                    
NuGet\Install-Package Knara.SourceGenerators.DesignPatterns.Mediator -Version 1.1.0
                    
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="Knara.SourceGenerators.DesignPatterns.Mediator" Version="1.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Knara.SourceGenerators.DesignPatterns.Mediator" Version="1.1.0" />
                    
Directory.Packages.props
<PackageReference Include="Knara.SourceGenerators.DesignPatterns.Mediator" />
                    
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 Knara.SourceGenerators.DesignPatterns.Mediator --version 1.1.0
                    
#r "nuget: Knara.SourceGenerators.DesignPatterns.Mediator, 1.1.0"
                    
#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 Knara.SourceGenerators.DesignPatterns.Mediator@1.1.0
                    
#: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=Knara.SourceGenerators.DesignPatterns.Mediator&version=1.1.0
                    
Install as a Cake Addin
#tool nuget:?package=Knara.SourceGenerators.DesignPatterns.Mediator&version=1.1.0
                    
Install as a Cake Tool

Declarative Mediator Generator

Build and Test Publish NuGet Packages NuGet NuGet .NET Standard 2.0 Language

A C# source generator that retrofits existing services with the mediator pattern using declarative attributes. Designed for gradual CQRS adoption in legacy codebases. Generates mediator infrastructure at compile-time using Roslyn analysis.

What It Does

This generator creates mediator boilerplate for two distinct scenarios:

1. CQRS-Style (New Code)

Clean separation of commands and queries with dedicated request/handler classes:

[Query(Name = "GetUserQuery", ResponseType = typeof(User))]
public record GetUserRequest(int UserId);

[QueryHandler(Name="GetUserHandler", RequestType = typeof(GetUserQuery))]
public class GetUserService(IUserRepository repository) 
{
    public async Task<User> GetAsync(GetUserRequest request, CancellationToken ct) { ... }
}

2. Legacy Retrofitting (Existing Code)

Method-level attributes that wrap existing services without modification:

public class LegacyUserService
{
    [RequestHandler(Name="GetUserHandler")]
    public async Task<User> GetUserAsync(int userId, CancellationToken ct) { ... }
    
    [RequestHandler(Name="CreateUserHandler")]  
    public async Task AddNewUserAsync(NewUserModel model, CancellationToken ct) { ... }
    
    [RequestHandler(Name="LegacyUserUpdateUserHandler")]
	public async Task<User> UpdateAsync(int userId, string email, string firstName, DateTime updateDate, CancellationToken cancellationToken = default) { ... }
}

Both generate the same mediator infrastructure but serve different migration strategies.

Quick Start

Add the source generator to your project:

<ItemGroup> <ProjectReference Include="path/to/Knara.SourceGenerators.DesignPatterns.Mediator.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false" /> </ItemGroup>

Or via NuGet (when published):

dotnet add package Knara.SourceGenerators.DesignPatterns.Mediator

If you are using the generator in .net 4.+ projects, refer to this guide for additional steps.

Usage Patterns

CQRS-Style Usage

// Generated: GetUserQuery : IQuery<User>
var user = await mediator.Send(new GetUserQuery { UserId = 123 });

// Generated: CreateUserCommand : ICommand<bool>  
var success = await mediator.Send(new CreateUserCommand { Email = "test@example.com" });

Legacy Retrofitting Usage

// Generated: GetUserRequest : IRequest<User>
var user = await mediator.Send(new GetUserRequest { UserId = 123 });

// Generated: CreateUserRequest : IRequest
await mediator.Send(new CreateUserRequest { Email = "test@example.com" });

Registration

// In your Startup.cs or Program.cs if using .NET 6+ 
services.AddDeclarativeMediator(); // Auto-registers all handlers and services

If you are using the generator in .net 4.+ projects, you need to manually register the generated types and mediator.

When to Use Each Pattern

CQRS-Style ([Query]/[Command])

Use for:

  • New feature development
  • Clean architectural boundaries
  • Complex business domains
  • Teams adopting CQRS principles

Legacy Retrofitting ([RequestHandler])

Use for:

  • Existing codebases with established patterns
  • Gradual mediator adoption
  • Risk-averse migration strategies
  • Mixed architectural approaches during transition

Pros

Dual approach - Supports both clean CQRS and pragmatic retrofitting
Compile-time generation - No runtime reflection, better performance than MediatR
Non-breaking - Legacy services remain callable directly during transition
Type safety - All request routing resolved at compile-time
Minimal friction - Add attributes to existing code without restructuring

Cons

Complexity - Two different patterns in same codebase can confuse teams
Type proliferation - Generates many request/handler classes
Generated code debugging - Harder to troubleshoot than explicit implementations
Limited pipeline - Missing MediatR's rich behavior/middleware ecosystem
Learning curve - Teams need to understand both patterns and when to use each

Performance

Faster than MediatR due to compile-time generation:

  • Direct method calls vs reflection
  • Pattern matching vs runtime type resolution
  • GetRequiredService<ConcreteType>() vs generic service location

Limitations

This is NOT a drop-in MediatR replacement. Missing:

  • Pipeline behaviors and middleware
  • Request preprocessing/postprocessing
  • Polymorphic request handling
  • Validation pipeline integration
  • Advanced error handling patterns
  • Request/response decorators

For full-featured mediator requirements, use MediatR directly.

Migration Strategy

Recommended approach:

  1. Start with legacy pattern - Add [RequestHandler] to existing methods
  2. Establish mediator usage - Route new features through generated mediator
  3. Introduce CQRS gradually - Use [Query]/[Command] for new bounded contexts
  4. Migrate incrementally - Convert legacy handlers to CQRS as business needs require
  5. Consider full MediatR - When you need advanced pipeline features

Use Cases

✅ Good Fit

  • Legacy modernization with risk constraints
  • Mixed architectural periods during large migrations
  • Performance-sensitive applications where reflection overhead matters
  • Simple request/response patterns without complex pipelines
  • Teams learning mediator patterns incrementally

❌ Poor Fit

  • Greenfield projects (just use MediatR)
  • Complex pipeline requirements (validation, caching, logging, etc.)
  • Heavy behavior composition needs
  • Small codebases where generated complexity outweighs benefits
  • Teams wanting industry-standard patterns

Code Generation Output

For each pattern, the generator creates:

  • Request classes implementing appropriate interfaces
  • Handler classes wrapping your service methods
  • Mediator implementation with compile-time request routing
  • DI registration extensions for all generated types

Example generated structure:

├── GetUserQuery.Request.g.cs          # CQRS request class
├── GetUserHandler.Handler.g.cs        # CQRS handler wrapper  
├── GetUserRequest.Request.g.cs        # Legacy request class
├── GetUserHandler.Handler.g.cs        # Legacy handler wrapper
├── GeneratedMediator.g.cs             # Unified mediator implementation
└── MediatorDIExtensions.g.cs          # Service registration

Bottom Line

Consider this a stepping stone toward full mediator adoption rather than a permanent architectural decision.


Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.1.0 159 10/25/2025
1.0.3 192 9/26/2025
1.0.2 216 9/24/2025
1.0.1 202 9/24/2025
1.0.0 222 9/23/2025