MuhammedJavad / MediatR.Extensions.AttributedBehaviors

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MediatR.Extensions.AttributedBehaviors

CI NuGet

MediatR extension adding ability to specify pipeline behaviors using attributes on command class. Leverages Microsoft.Extensions.DependencyInjection as a DI container.

Ever found yourself confused when looking for behaviors that are attached to the pipeline you are about to debug? Keeping all behaviors specified within the command class makes it really clear.

// Instead of this
 services.AddScoped<IPipelineBehavior<MyRequest, MyReturnType>, MyFirstPipelineBehavior<MyRequest, MyReturnType>>()
         .AddScoped<IPipelineBehavior<MyRequest, MyReturnType>, MySecondPipelineBehavior>();

// You write this
[MediatRBehavior(typeof(MyFirstPipelineBehavior<MyRequest, MyReturnType>))]
[MediatRBehavior(typeof(MySecondPipelineBehavior))]
public class MyRequest : IRequest<MyReturnType> { }

You immediately see all the behaviors your request passes through in order as they are specified. No need to search in your code base for behaviors installation to see what behaviors are used.

Install

Install with Package Manager Console

Install-Package MediatR.Extensions.AttributedBehaviors

Install with .NET CLI

dotnet add package MediatR.Extensions.AttributedBehaviors

How to use

Setup - Add configuration in startup.cs

public void ConfigureServices(IServiceCollection services)
{   
    var executingAssembly = Assembly.GetExecutingAssembly()
    // Add MediatR
    services.AddMediatR(executingAssembly);

    // optionally register open generics universal behaviors (e.g. logging)
    // before registering attributed behaviors
    services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggingPipelineBehavior<,>));

    //Add Attributed Behaviors
    services.AddMediatRAttributeBehaviors(executingAssembly);
    
    //Add other stuff
    ...
}

Use

You no longer need to register your behaviors in service collection. You can keep them clearly visible right where they are used

// no longer needed
 services.AddScoped<IPipelineBehavior<GetValidEventUrlRequest, ValidEventUrl>, ResolveEventIdByPublicIdPipelineBehavior<GetValidEventUrlRequest, ValidEventUrl>>()
         .AddScoped<IPipelineBehavior<GetValidEventUrlRequest, ValidEventUrl>, CheckEventDisabledPipelineBehavior<GetValidEventUrlRequest, ValidEventUrl>>();



// instead you can just simply specify them like this
[MediatRBehavior(typeof(ResolveEventIdByPublicIdPipelineBehavior<GetValidEventUrlRequest, ValidEventUrl>))]
[MediatRBehavior(typeof(CheckEventDisabledPipelineBehavior<GetValidEventUrlRequest, ValidEventUrl>))]
public class GetValidEventUrlRequest : IRequest<ValidEventUrl>
{
    public string PublicId { get; set; }
    public int EventId { get; set; }
}

Custom behavior life-cycle

By default, Scoped lifetime is used. You can use your own lifetime as desired

// singleton behavior
[MediatRBehavior(typeof(MySingletonPipelineBehavior<MyQuery>), serviceLifetime: ServiceLifetime.Singleton)]
public class MyQuery : IRequest

Custom behavior ordering

By default, behaviors are orders as they are specified top-to-bottom. If you ever need to specify your custom ordering, you can.

// override default top->bottom ordering
[MediatRBehavior(typeof(SecondPipelineBehavior<MyQuery>), order: 2)]
[MediatRBehavior(typeof(FirstPipelineBehavior<MyQuery>), order: 1)]
public class MyQuery : IRequest

About

License:MIT License


Languages

Language:C# 100.0%