Skip to content

Latest commit

 

History

History
272 lines (214 loc) · 10.1 KB

File metadata and controls

272 lines (214 loc) · 10.1 KB

AdaskoTheBeAsT.MediatR.SimpleInjector and AdaskoTheBeAsT.MediatR.SimpleInjector.AspNetCore

MediatR extensions for SimpleInjector.

Badges

CodeFactor Build Status Azure DevOps tests Azure DevOps coverage Quality Gate Status Sonar Tests Sonar Test Count Sonar Test Execution Time Sonar Coverage Nuget

Usage in AspNetCore

Scans assemblies and adds handlers, preprocessors, and postprocessors implementations to the SimpleInjector container. Additionally it register decorator which passes HttpContext.RequestAborted cancellation token from asp.net core controllers to MediatR.
Install package AdaskoTheBeAsT.MediatR.SimpleInjector.AspNetCore.
There are few options to use with Container instance:

  1. Marker type from assembly which will be scanned

    container.AddMediatRAspNetCore(typeof(MyHandler), type2 /*, ...*/);
  2. Assembly which will be scanned

    container.AddMediatRAspNetCore(assembly, assembly2 /*, ...*/);
  3. Full configuration

    var testMediator = new Mock<IMediator>();
    container.AddMediatR(
        cfg =>
        {
            cfg.Using(() => testMediator.Object);
            cfg.WithHandlerAssemblyMarkerTypes(typeof(MyMarkerType));
            cfg.UsingBuiltinPipelineProcessorBehaviors(true);
            cfg.UsingPipelineProcessorBehaviors(typeof(CustomPipelineBehavior<,>));
            cfg.UsingStreamPipelineBehaviors(typeof(CustomStreamPipelineBehavior<,>));
        });

Usage in other project types

Scans assemblies and adds handlers, preprocessors, and postprocessors implementations to the SimpleInjector container.
Install package AdaskoTheBeAsT.MediatR.SimpleInjector.
There are few options to use with Container instance:

  1. Marker type from assembly which will be scanned

    container.AddMediatR(typeof(MyHandler), type2 /*, ...*/);
  2. List of assemblies which will be scanned.

    Below is sample for scanning assemblies from some solution.

    [ExcludeFromCodeCoverage]
    public static class MediatRConfigurator
    {
        private const string NamespacePrefix = "YourNamespace";
    
        public static void Configure(Container container)
        {
            var loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
            var assemblies = new List<Assembly>();
            var mainAssembly = typeof(MediatRConfigurator).GetTypeInfo().Assembly;
            var refAssemblies = mainAssembly.GetReferencedAssemblies();
            foreach (var assemblyName in refAssemblies
                .Where(a => a.FullName.StartsWith(NamespacePrefix, StringComparison.OrdinalIgnoreCase)))
                {
                    var assembly = loadedAssemblies.Find(l => l.FullName == assemblyName.FullName)
                        ?? AppDomain.CurrentDomain.Load(assemblyName);
                    assemblies.Add(assembly);
                }
            container.AddMediatR(assemblies);
        }
    }

This will register:

  • IMediator as Singleton
  • IRequestHandler<> concrete implementations as Transient
  • INotificationHandler<> concrete implementations as Transient
  • IStreamRequestHandler<> concrete implementations as Transient

Advanced usage

Setting up custom IMediator instance and marker type from assembly for unit testing (Moq sample)

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

Setting up custom IMediator implementation and marker type from assembly

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

Setting up custom IMediator implementation and assemblies to scan

 container.AddMediatR(
     cfg =>
     {
         cfg.Using<MyCustomMediator>();
         cfg.WithAssembliesToScan(assemblies);
     });

Setting assemblies to scan and different lifetime for IMediator implementation

 container.AddMediatR(
     cfg =>
     {
         cfg.WithAssembliesToScan(assemblies);
         cfg.AsScoped();
     });

Setting assemblies to scan and additionally enabling all builtin behaviors and user defined processors/handlers

This will register following behaviors:

  • RequestPreProcessorBehavior<,>
  • RequestPostProcessorBehavior<,>
  • RequestExceptionProcessorBehavior<,>
  • RequestExceptionActionProcessorBehavior<,>

and all user defined implementation of processors and handlers:

  • IRequestPreProcessor<>

  • IRequestPostProcessor<,>

  • IRequestExceptionHandler<,,>

  • IRequestExceptionActionHandler<,>

     container.AddMediatR(
         cfg =>
         {
             cfg.WithAssembliesToScan(assemblies);
             cfg.UsingBuiltinPipelineProcessorBehaviors(true);
         });

Setting assemblies to scan and additionally enabling chosen builtin behaviors and user defined processors/handlers

This will register following behaviors:

  • RequestPreProcessorBehavior<,>
  • RequestExceptionProcessorBehavior<,>

and all user defined implementation of processors and handlers:

  • IRequestPreProcessor<>

  • IRequestExceptionHandler<,,>

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

Setting assemblies to scan and additionally custom stream request handlers behaviors

This will register following stream behaviors:

  • CustomStreamPipelineBehavior<,>

     container.AddMediatR(
         cfg =>
         {
             cfg.WithAssembliesToScan(assemblies);
             cfg.UsingStreamPipelineBehaviors(typeof(CustomStreamPipelineBehavior<,>));
         });

Setting assemblies to scan and additionally enabling chosen builtin behaviors and user defined processors/handlers also with custom Pipeline Process Behaviors

 container.AddMediatR(
     cfg =>
     {
         cfg.WithAssembliesToScan(assemblies);
         cfg.UsingBuiltinPipelineProcessorBehaviors(
             requestPreProcessorBehaviorEnabled: true,
             requestPostProcessorBehaviorEnabled: false,
             requestExceptionProcessorBehaviorEnabled: true,
             requestExceptionActionProcessorBehaviorEnabled: false);
         cfg.UsingPipelineProcessorBehaviors(typeof(CustomPipelineBehavior<,>));
         cfg.WithRequestPreProcessorTypes(typeof(FirstRequestPreProcessor<>), typeof(SecondRequestPreProcessor<>));
         cfg.WithRequestPostProcessorTypes(typeof(FirstRequestPostProcessor<,>), typeof(SecondRequestPostProcessor<,>));
         cfg.WithRequestExceptionProcessorTypes(typeof(FirstRequestExceptionProcessor<,,>), typeof(SecondRequestExceptionProcessor<,,>));
         cfg.WithRequestExceptionActionProcessorTypes(typeof(FirstRequestExceptionActionProcessor<,>), typeof(SecondRequestExceptionActionProcessor<,>));
     });

Setting assemblies to scan and additionally enabling chosen builtin behaviors and processors with specific order

Setting assemblies to scan and set WithNotificationPublisherForeachAwait NotificationPublisher

 container.AddMediatR(
     cfg =>
     {
         cfg.WithAssembliesToScan(assemblies);
         cfg.WithNotificationPublisherForeachAwait();
     });
``

### Setting assemblies to scan and set TaskWhenAllPublisher NotificationPublisher

```cs
 container.AddMediatR(
     cfg =>
     {
         cfg.WithAssembliesToScan(assemblies);
         cfg.WithNotificationPublisherTaskWhenAll();
     });

Setting assemblies to scan and set custom NotificationPublisher

 container.AddMediatR(
     cfg =>
     {
         cfg.WithAssembliesToScan(assemblies);
         cfg.WithNotificationPublisherCustom<CustomNotificationPublisher>();
     });

Thanks to

Code originates from MediatR.Extensions.Microsoft.DependencyInjection and was changed to work with SimpleInjector.