MediatR Behaviors

MediatR BehaviorsI was happy and surprised to see that MediatR v3.0 was released yesterday.  One of the new features, which I was really looking forward to are pipeline behaviors.

A pipeline behavior is an implementation of IPipelineBehavior<TRequest, TResponse>. It represents a similar pattern to filters in ASP.NET MVC/Web API or pipeline behaviors in NServiceBus.

Changes

There are a couple major breaking changes to v3.  All of them I’m fairly happy about actually.

Messages

There is no distinction between sync, async (cancellable) requests or notifications.

You simply implement either IRequest or INotification.

You must still create the appropriate handler via either IRequestHandler, IAsyncRequestHandlerICancellableAsyncRequestHandler.

Async

To send a request or publish a notification simply use Task Send(IRequest) or Task Publish(INotification)

No longer does it have the “Async” convention of appending to the method name.  I know this is often debated about this convention.  I don’t mind it at all since there are no sync methods.

Behaviors

The new addition is the interface IPipelineBehavior<TRequest, TResponse>

This allows you to create implementation(s) that will invoked in the order they are registered with your container (returned from the MultiInstanceFactory delegate).

The simplest implementation, that does nothing but call the next possible behavior.

You can see how you can use this to create Pre and Post behaviors to create a pipeline.

Pre & Post Processors

Thankfully, these have already been created and built-in to v3.

RequestPreProcessorBehavior<TRequest, TResponse> and RequestPostProcessorBehavior<TRequest, TResponse> to the rescue.

These can be used to implementing the appropriate interface of IRequestPreProcess<TRequest,TResponse> and IRequestPostProcessor<TRequest,TResponse>

Note: Be sure to register your  IRequestPreProcess<TRequest,TResponse> and IRequestPostProcessor<TRequest,TResponse> as well as RequestPreProcessorBehavior<TRequest, TResponse> and RequestPostProcessorBehavior<TRequest, TResponse>  with your container.

Test Drive

I figured I would use my ASP.NET Core MVC Music Store application as a test bed.

You can refer to my Fat Controller CQRS Diet: Command Pipeline post to see how created a pipeline in MediatR v2.  It involved creating wrapper/decorator with StructureMap.

This is incredibly straight forward and does all the heavy lifting that the pipeline decorator that I created previous.

For our MusicStore app, we can change our AddToCart for logging to be done like this.

The above code completely removed my need for my custom Pipeline decorator using StructureMap.  Win.

ASP.NET Extension

If you are using ASP.NET Core, check out the MediatR.Extensions.Microsoft.DependencyInjection v2.x package.  It has also been updated to support MediatR v3.

It adds several extension methods, one of which is IServiceCollection.AddMediatR(Assembly) to register all the Handlers and Pre/PostProcessor in a given assembly.

Comments

Are you using MediatR?  Do you plan on upgrading to v3?  I love hearing your comments, questions and recommendations!  Please post a comments or on Twitter.


  • Derek, thanks so much for the quick and timely blog in MediatR 3.0. I forked and pulled the code locally last night, and was exploring the new IPipelineBehavior interface, but looks like you beat me to the punch with a blog post. I’ll definitely be using your blog as a guide to implementing pipeline behavior in MediatR 3.0 for an ASP.NET Core project I’ve been working on.

    • Thanks. Don’t stop this post from creating your own. There’s likely value in creating your own post about your experience using the new behaviors.

  • I love MediatR, but we haven’t gone all async yet so I’m not switching to v3 until we’re ready for that. I guess it’s nice MediatoR has its own behaviors, but I’ve been behaviors for a while through our SimpleInjector container decorators so no rush on that.

  • I was writing about MediatR the other day (which turned out to be a little late) comparing it with MicroBus (which is the mediator I’ve been writing). You can check it out here https://www.lavinski.me/comparing-microbus-and-mediatr/, I had to update the post after finding this https://github.com/jbogard/MediatR/wiki/Behaviors

  • Ben Edwards

    I don’t think the “AddToCartPostHandler” example above would be a good way to implement a behaviour. It works fine for a single behaviour, but if you have multiple then it could have unintended side effects, especially if the order of execution matters.

    As an example, my 2.x pipeline has 2 “pre-behaviours” – one that handled authorization (does the user have permission to do this) and one that handled validation (is the IRequest in a valid state). It is important that these are executed in order otherwise the errors returned could result in security issues, giving out unintended information about your api.

    In v3, i implement a generic authorization behaviour and a validation behaviour, which then accept an IAuthorizor and IValidator respectively. These behaviours are added to DI in the order i want them to execute.

    Does this sound like something I should be doing, or is it possibly over engineering the solution?

    • Yes the order in which you register with your DI Container matters, as you mentioned. As with my example post on creating a decorator using v2, you could basically do the same thing in v3 by implementing IPipelineBehavior and having your implementation take collections of IValidator and IAuthorizor and then invoke them prior to calling the next behavior. Meaning you could have one implementation of IPipelineBehavior that worked like your v2 did.