Using Mediator Pipelines in ASP.NET Core Applications

Intercept commands, queries and events to apply transversal behavior

João Simões
Nov 2, 2020 · 5 min read

In my previous article I explained how you could implement Command Query Responsibility Segregation (CQRS) and Event Sourcing (ES) patterns using a mediator instance from SimpleSoft.Mediator in ASP.NET Core applications.

This time I’m going to explain how to intercept commands, queries and events, making it possible to apply transversal behavior before they reach the handlers, reducing significantly the amount of boilerplate and duplicated code.

Transaction management, logging, auditing, caching or validations are some of the good examples where pipelines can be very helpful. Imagine the following chains:

Not only you can plugin any pipeline at will without changing the handlers implementation, you can also be specific to the entities each pipeline is interested.

Pipelines

Mediator pipelines are represented by the interface (or the abstract class ) with methods to intercept each entity type:

You receive a delegate for the next pipe and the entity, so the concept is very simple: either do some work before or after invoking the next pipe, or break the chain by returning or throwing an exception.

Pipelines are executed by the same order they are added to the container so, to be deterministic, don’t scan the assemblies for classes implementing .

Commands pipeline

Intercept commands sent into the mediator by implementing the methods :

Sequence diagram for commands

Queries pipeline

Intercept queries being fetched from the mediator by implementing the methods :

Sequence diagrams for queries

Events pipeline

Intercept events before being broadcasted by the mediator into all the handlers by implementing the method :

Sequence diagrams for events

The project

To make it easier, we are going to leverage on the previous article and continue from there. As a reminder, we implemented an endpoint to manage products with the following:

  • GET /products — search for products using some filters ();
  • GET /products/{id} — get a product by its unique identifier ();
  • POST /products — create a product ( and );
  • PUT /products/{id} — update a product by its unique identifier ( and );
  • DELETE /products/{id} — delete a product by its unique identifier ( and );

The complete source code can be found on GitHub.

The pipelines

Since the objective of this article is to show how to implement pipelines in the mediator, the following should be enough:

  • LoggingPipeline — serializes every command, queries, events and results as JSON into the log if is enabled;
  • TimeoutPipeline — cancels the handler execution if it takes more than a given set of time;

Start by creating a folder at the project root level.

LoggingPipeline

Because we don’t want logging to affect the timeout, this will be the first pipeline to be added to the chain.

Inside the folder, create a class implementing . This pipeline will receive an instance and uss to serialize the objects:

Open the file and register the pipeline into the mediator:

Open the file and set the default log level to :

If you now start the server and do some actions in the API, like creating or searching for products, you should start seeing your objects being serialized:

As a note, if you find this helpful for your APIs, you can use the NuGet SimpleSoft.Mediator.Microsoft.Extensions.LoggingPipeline. Just give a look at the file from the example API.

TimeoutPipeline

Inside the folder, create a class implementing . For simplicity, the timeout value will be fixed, but could be received as an options from the container.

Once again, open the file and register the pipeline into the mediator after the logging pipe:

If you now open any of your handlers and add an into the methods you should receive a . I added one when searching for products:

If you look at the stack trace, you’ll see the invocation order was kept:

Your project and final file:

Conclusion

I hope this article gave you a good idea about mediator pipelines and how you can use them to empower your solutions, making them more resilient to developer mistakes (like forgetting to save changes into the database).

For me, this is one of the strongest aspects of the mediator pattern and one of the main reason I always use this pattern even when implementing minimum viable products.

Also, check my articles about pipeline validation and transaction management:

The Startup

Get smarter at building your thing. Join The Startup’s +794K followers.

Sign up for Top 10 Stories

By The Startup

Get smarter at building your thing. Subscribe to receive The Startup's top 10 most read stories — delivered straight into your inbox, once a week. Take a look.

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

João Simões

Written by

Solutions Architect trying to solve world “problems”!

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +794K followers.

João Simões

Written by

Solutions Architect trying to solve world “problems”!

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +794K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store