IronAlpine.Mediator 3.0.0

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

IronAlpine.Mediator

Request/response orchestration with validation, caching, and behavior pipeline.

  • Target Frameworks: net9.0, net10.0
  • Dependencies: FluentValidation, Microsoft.Extensions.DependencyInjection
  • Package Size: ~120 KB
  • Replaces: 6 v2 packages (Mediator, Abstractions, DI, Validation.Fluent, Caching, Locking.Abstractions)

What It Is

IronAlpine.Mediator provides the application layer:

  • Request/Response — decoupled command and query handlers
  • Validation — FluentValidation integration + automatic behavior
  • Caching — per-query TTL with automatic invalidation
  • Behaviors — middleware pipeline (Slots 1-3 of 5)

Installation

dotnet add package IronAlpine.Mediator

Quick Setup

services.AddIronAlpineMediator(cfg =>
{
    cfg.RegisterServicesFromAssembly(typeof(MyApplication).Assembly);
    cfg.UseValidationBehavior(typeof(MyApplication).Assembly);
    cfg.UseCachingBehavior();  // Optional
});

Define Requests & Handlers

Query (Read-Only)

// 1. Define request (immutable)
public class GetTimeOffByIdQuery : IRequest<TimeOffDetailsResponse>
{
    public Guid TimeOffId { get; set; }
}

// 2. Define validator (FluentValidation)
public class GetTimeOffByIdQueryValidator : AbstractValidator<GetTimeOffByIdQuery>
{
    public GetTimeOffByIdQueryValidator()
    {
        RuleFor(x => x.TimeOffId).NotEmpty();
    }
}

// 3. Define handler
public class GetTimeOffByIdQueryHandler
    : IRequestHandler<GetTimeOffByIdQuery, TimeOffDetailsResponse>
{
    private readonly IRepository<TimeOff> _repository;

    public async Task<TimeOffDetailsResponse> Handle(
        GetTimeOffByIdQuery request,
        CancellationToken cancellationToken)
    {
        var timeOff = await _repository.GetByIdAsync(request.TimeOffId, cancellationToken);
        return new TimeOffDetailsResponse { ... };
    }
}

// 4. Send request (in controller/service)
var response = await _mediator.Send(new GetTimeOffByIdQuery { TimeOffId = id });

Command (Mutation)

// 1. Define request
public class ApproveTimeOffCommand : IRequest<Unit>
{
    public Guid TimeOffId { get; set; }
    public string Comment { get; set; }
}

// 2. Define validator
public class ApproveTimeOffCommandValidator : AbstractValidator<ApproveTimeOffCommand>
{
    public ApproveTimeOffCommandValidator()
    {
        RuleFor(x => x.TimeOffId).NotEmpty();
        RuleFor(x => x.Comment).NotEmpty().MaximumLength(500);
    }
}

// 3. Define handler
public class ApproveTimeOffCommandHandler
    : IRequestHandler<ApproveTimeOffCommand, Unit>
{
    private readonly IUnitOfWork _unitOfWork;

    public async Task<Unit> Handle(ApproveTimeOffCommand request, CancellationToken ct)
    {
        var repo = _unitOfWork.Repository<TimeOff>();
        var timeOff = await repo.GetByIdAsync(request.TimeOffId, ct);
        
        timeOff.Approve(new UserId(Guid.NewGuid()), request.Comment);
        repo.Update(timeOff);
        await _unitOfWork.SaveChangesAsync(ct);

        return Unit.Value;
    }
}

// 4. Send command
await _mediator.Send(new ApproveTimeOffCommand { TimeOffId = id, Comment = "OK" });

Behavior Pipeline (Slots 1-3)

Mediator owns 3 of 5 behavior slots:

Slot Behavior Purpose Opt-In
1 LoggingBehavior Logs request/response Yes (Observability)
2 CachingBehavior Caches query results Yes
3 ValidationBehavior Validates request No (always on)

Enable Caching

// appsettings.json
{
  "IronAlpine": {
    "Mediator": {
      "Caching": {
        "Enabled": true,
        "DefaultTTLSeconds": 300  // 5 minutes
      }
    }
  }
}

// Setup
services.AddIronAlpineMediator(cfg =>
{
    cfg.UseCachingBehavior();
});

Enable Validation

// appsettings.json
{
  "IronAlpine": {
    "Mediator": {
      "Validation": {
        "Enabled": true
      }
    }
  }
}

// Setup (required)
services.AddIronAlpineMediator(cfg =>
{
    cfg.UseValidationBehavior(typeof(MyApplication).Assembly);
});

Configuration

{
  "IronAlpine": {
    "Mediator": {
      "Validation": {
        "Enabled": true,
        "Assemblies": ["MyApp.Application"]
      },
      "Caching": {
        "Enabled": true,
        "DefaultTTLSeconds": 300
      }
    }
  }
}
Setting Default Purpose
Validation.Enabled true Enable FluentValidation behavior
Caching.Enabled true Enable query caching
Caching.DefaultTTLSeconds 300 Cache TTL in seconds

Custom Behaviors

Add your own behaviors to the pipeline:

// 1. Implement IPipelineBehavior<TRequest, TResponse>
public class MyCustomBehavior<TRequest, TResponse>
    : IPipelineBehavior<TRequest, TResponse>
    where TRequest : IRequest<TResponse>
{
    public async Task<TResponse> Handle(
        TRequest request,
        RequestHandlerDelegate<TResponse> next,
        CancellationToken cancellationToken)
    {
        // Before handler
        Console.WriteLine($"Handling {typeof(TRequest).Name}");
        
        var response = await next();
        
        // After handler
        Console.WriteLine($"Handled {typeof(TRequest).Name}");
        
        return response;
    }
}

// 2. Register it
services.AddTransient(
    typeof(IPipelineBehavior<,>),
    typeof(MyCustomBehavior<,>));

Best Practices

✅ DO

// 1. Use single responsibility
public class GetTimeOffByIdQuery : IRequest<TimeOffDetailsResponse> { }
public class ApproveTimeOffCommand : IRequest<Unit> { }

// 2. Validate early
RuleFor(x => x.TimeOffId).NotEmpty();

// 3. Use interfaces
private readonly IRepository<TimeOff> _repository;

// 4. Handle cancellation
public async Task<TResponse> Handle(
    TRequest request,
    CancellationToken cancellationToken)
{
    // Use cancellationToken in all async operations
    return await _repository.GetByIdAsync(id, cancellationToken);
}

❌ DON'T

// 1. Bypass validation manually
if (request.TimeOffId == Guid.Empty) { ... }  // Validator should do this

// 2. Catch validation exceptions
// Validation behavior handles them, return ProblemDetails automatically

// 3. Return Task instead of awaiting
return repository.GetByIdAsync(...);  // Should be awaited

// 4. Ignore CancellationToken
public async Task<TResponse> Handle(TRequest request, CancellationToken ct)
{
    return await _repository.GetByIdAsync(...);  // Missing ct parameter
}

Integration with Other Packages

  • IronAlpine.Kernel: Request types use domain types (TimeOffId, UserId, etc.)
  • IronAlpine.Data: Handlers use IRepository<T>, IUnitOfWork for persistence
  • IronAlpine.Observability: LoggingBehavior (Slot 1) added automatically
  • IronAlpine.Web: Controllers send requests via mediator

Troubleshooting

Q: Validator not running?
A: Ensure UseValidationBehavior(assembly) called with correct assembly containing validators.

Q: Caching not working?
A: Set Mediator.Caching.Enabled: true and call UseCachingBehavior().

Q: Behavior order wrong?
A: Behaviors register in order. Check Program.cs Setup is: Mediator → Data → Observability.

Examples

See IRONALPINE_V3_DOCUMENTATION.md for detailed examples.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on IronAlpine.Mediator:

Package Downloads
IronAlpine.Mediator.DependencyInjection

Dependency injection integration for IronAlpine mediator, including assembly scanning and open behavior registration.

IronAlpine.Data

EFCore data stack for IronAlpine: repositories, interceptors (audit, soft-delete, versioning), mediator behaviors (AuditingBehavior, TransactionBehavior, UnitOfWork), domain event dispatching, and Redis cache. Unified entry point: AddIronAlpineData<TDbContext>. All implementations are internal.

IronAlpine.EventBus

Kafka-backed event bus with outbox/inbox pattern, dead letter support, and replay functionality. Unified namespace: IronAlpine.EventBus. Kafka implementation is internal; only contracts and topology builder are public. SSL cert parameters fully configurable (SslCaLocation, SslCertLocation, SslKeyLocation, SslKeyPassword).

IronAlpine.Observability

Logging (Serilog), OpenTelemetry tracing/metrics, and Resilience (Polly) for IronAlpine microservices. Provides UseLoggingBehavior() extension for the mediator pipeline. EventMetadataContext and correlation tracking included. All implementations internal.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0 188 7/1/2026
Loading failed

Stable mediator release with request/response, notification publish strategies, streaming, and dependency injection integration.