Skip to content

AdaskoTheBeAsT/AdaskoTheBeAsT.MediatR.SimpleInjector

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

170 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MediatR.SimpleInjector

Seamless MediatR integration for SimpleInjector with automatic configuration and convention-based registration

CodeFactor Build Status Azure DevOps tests Azure DevOps coverage Quality Gate Status Sonar Coverage Nuget

Why This Library?

If you're using MediatR with SimpleInjector, this library eliminates all the boilerplate. It provides:

  • One-line setup - Scan assemblies and auto-register all handlers, behaviors, and processors
  • Smart defaults - Works out of the box with sensible conventions
  • ASP.NET Core magic - Automatic HttpContext.RequestAborted token propagation to MediatR requests
  • Flexible configuration - Override anything when you need fine-grained control
  • Full MediatR support - Handlers, notifications, streams, behaviors, pre/post processors, and exception handling
  • .NET 10 ready - Updated to the latest .NET and MediatR versions

Quick Start

For ASP.NET Core Projects

Install the package:

dotnet add package AdaskoTheBeAsT.MediatR.SimpleInjector.AspNetCore

Register MediatR:

using AdaskoTheBeAsT.MediatR.SimpleInjector;

// In your Startup.cs or Program.cs
container.AddMediatRAspNetCore(typeof(Startup));

That's it! All handlers in the assembly containing Startup are registered, and cancellation tokens from HTTP requests are automatically passed to MediatR.

For Other Project Types (Console, WPF, etc.)

Install the package:

dotnet add package AdaskoTheBeAsT.MediatR.SimpleInjector

Register MediatR:

using AdaskoTheBeAsT.MediatR.SimpleInjector;

container.AddMediatR(typeof(MyHandler));

What Gets Registered?

By default, the library registers:

Interface Lifestyle
IMediator Singleton
IRequestHandler<TRequest, TResponse> Transient
INotificationHandler<TNotification> Transient
IStreamRequestHandler<TRequest, TResponse> Transient

Common Usage Patterns

Scanning Multiple Assemblies

// By marker types
container.AddMediatR(typeof(MyHandler), typeof(AnotherHandler));

// By assembly instances
container.AddMediatR(assembly1, assembly2, assembly3);

Scanning All Assemblies in Your Solution

public static class MediatRConfigurator
{
    private const string NamespacePrefix = "YourCompany.YourApp";

    public static void Configure(Container container)
    {
        var assemblies = AppDomain.CurrentDomain.GetAssemblies()
            .Where(a => a.FullName.StartsWith(NamespacePrefix, StringComparison.OrdinalIgnoreCase))
            .ToList();
            
        container.AddMediatR(assemblies.ToArray());
    }
}

ASP.NET Core with Multiple Assemblies

container.AddMediatRAspNetCore(
    typeof(Startup),           // Web project
    typeof(CreateOrderHandler), // Application layer
    typeof(SendEmailHandler)    // Infrastructure layer
);

Configuration Options

Change IMediator Lifestyle

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.AsScoped(); // Default is Singleton
});

Use Custom IMediator Implementation

container.AddMediatR(cfg =>
{
    cfg.Using<MyCustomMediator>();
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
});

Mock IMediator for Testing

var mockMediator = new Mock<IMediator>();
container.AddMediatR(cfg =>
{
    cfg.Using(() => mockMediator.Object);
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
});

Advanced Configuration

Pipeline Behaviors

Enable all built-in MediatR behaviors:

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.UsingBuiltinPipelineProcessorBehaviors(true);
});

This registers:

  • RequestPreProcessorBehavior<,> + all IRequestPreProcessor<> implementations
  • RequestPostProcessorBehavior<,> + all IRequestPostProcessor<,> implementations
  • RequestExceptionProcessorBehavior<,> + all IRequestExceptionHandler<,,> implementations
  • RequestExceptionActionProcessorBehavior<,> + all IRequestExceptionAction<,> implementations

Enable specific behaviors only:

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.UsingBuiltinPipelineProcessorBehaviors(
        requestPreProcessorBehaviorEnabled: true,
        requestPostProcessorBehaviorEnabled: false,
        requestExceptionProcessorBehaviorEnabled: true,
        requestExceptionActionProcessorBehaviorEnabled: false);
});

Add custom pipeline behaviors:

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.UsingPipelineProcessorBehaviors(
        typeof(LoggingBehavior<,>),
        typeof(ValidationBehavior<,>),
        typeof(TransactionBehavior<,>));
});

Add custom stream pipeline behaviors:

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.UsingStreamPipelineBehaviors(typeof(StreamLoggingBehavior<,>));
});

Notification Publishers

Use ForeachAwait (default):

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.WithNotificationPublisherForeachAwait();
});

Use TaskWhenAll for parallel execution:

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.WithNotificationPublisherTaskWhenAll();
});

Use custom notification publisher:

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.WithNotificationPublisherCustom<MyCustomPublisher>();
});

Fine-Grained Processor Control

Control exactly which pre/post processors and exception handlers get registered:

container.AddMediatR(cfg =>
{
    cfg.WithHandlerAssemblyMarkerTypes(typeof(MyHandler));
    cfg.UsingBuiltinPipelineProcessorBehaviors(
        requestPreProcessorBehaviorEnabled: true,
        requestPostProcessorBehaviorEnabled: true,
        requestExceptionProcessorBehaviorEnabled: true,
        requestExceptionActionProcessorBehaviorEnabled: true);
    
    // Register specific processors in order
    cfg.WithRequestPreProcessorTypes(
        typeof(LoggingPreProcessor<>),
        typeof(ValidationPreProcessor<>));
    
    cfg.WithRequestPostProcessorTypes(
        typeof(CacheInvalidationPostProcessor<,>),
        typeof(NotificationPostProcessor<,>));
    
    cfg.WithRequestExceptionProcessorTypes(
        typeof(LoggingExceptionProcessor<,,>),
        typeof(RetryExceptionProcessor<,,>));
    
    cfg.WithRequestExceptionActionProcessorTypes(
        typeof(AlertingExceptionAction<,>));
});

Package Information

Package NuGet
AdaskoTheBeAsT.MediatR.SimpleInjector NuGet
AdaskoTheBeAsT.MediatR.SimpleInjector.AspNetCore NuGet
AdaskoTheBeAsT.MediatR.SimpleInjector.AspNet NuGet

Compatibility

  • .NET Standard 2.0+ - Works with .NET Framework 4.6.1+, .NET Core 2.0+, .NET 5+
  • MediatR 13.1.0+ - Latest MediatR version
  • SimpleInjector 5.5.0+ - Latest SimpleInjector version

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.


License

This project is licensed under the MIT License - see the LICENSE file for details.


Credits

Special thanks to:

This library was inspired by MediatR.Extensions.Microsoft.DependencyInjection and adapted for SimpleInjector's unique capabilities.


⭐ Star this repo if you find it useful!

Made with ❤️ by Adam "AdaskoTheBeAsT" Pluciński

About

MediatR extension to SimpleInjector

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages