Middlewares

A middleware is a piece of logic that is executed between the mediator and the message handler. It has been designed to be very similar to Asp.Net Core middlewares. You can use middlewares to create any pipeline that you need for your queries and events.

../../_images/mediate_middleware_flow.png

Each middleware can do the following things:

  • Choose to invoke the next element in the pipeline.

  • Do logic before and after calling the next element in the pipeline.

Note

The middlewares are invoked in the same registration order.

Query Middleware

A query middleware allows you to create a specific pipeline for a query.

Middleware creation

To create a query middleware you have to implement the IQueryMiddleware<TQuery,TResult> generic interface.

/// <summary>
/// Interface to implement a middleware to process a query before it reaches it's handler.
/// <typeparam name="TQuery">Query type</typeparam>
/// <typeparam name="TResult">Query response type</typeparam>
/// </summary>
public interface IQueryMiddleware<in TQuery, TResult> where TQuery : IQuery<TResult>
{
       /// <summary>
       /// Invoke the middleware logic
       /// </summary>
       /// <param name="query">Query object</param>
       /// <param name="cancellationToken"></param>
       /// <param name="next">Delegate that encapsulates a call to the next element in the pipeline</param>
       /// <returns></returns>
       Task<TResult> Invoke(TQuery query, CancellationToken cancellationToken, NextMiddlewareDelegate<TResult> next);
}

For example:

public class SampleQueryLoggerMiddleware : IQueryMiddleware<MyQuery, string>
{
     private readonly ILogger<SampleQueryLoggerMiddleware> _logger;

     public SampleQueryLoggerMiddleware(ILogger<SampleQueryLoggerMiddleware> logger)
     {
           _logger = logger;
     }

     public async Task<string> Invoke(MyQuery query, CancellationToken cancellationToken, NextMiddlewareDelegate<string> next)
     {
          _logger.LogDebug("Query log: ", query);

           //invoke the next middleware in the pipeline
           return await next();
     }
}

Note

The NextMiddlewareDelegate<TResult> next parameter is a delegate that encapsulates the call to the next element in the pipeline.

Query middleware pipeline

The following diagram demonstrates how middlewares are invoked under the hood.

../../_images/query_middleware_flow.png

Important

You have to invoke next to execute the next element in the pipeline. You can short circuit the pipeline simply don’t invoking next.

Event Middleware

An event middleware allows you to create a specific pipeline for an event.

Middleware creation

To create an event middleware you have to implement the IEventMiddleware<TEvent> generic interface.

/// <summary>
/// Interface to implement a middleware to process an event before it reaches it's handlers.
/// <typeparamref name="TEvent">Event type</typeparam>
/// </summary>
public interface IEventMiddleware<in TEvent> where TEvent : IEvent
{
    /// <summary>
    /// Invoke the middleware logic
    /// </summary>
    /// <param name="event">Event object</param>
    /// <param name="cancellationToken"></param>
    /// <param name="next">Delegate that encapsulates a call to the next element in the pipeline</param>
    /// <returns></returns>
    Task Invoke(TEvent @event, CancellationToken cancellationToken, NextMiddlewareDelegate next);
}

For example:

public class SampleEventLoggerMiddleware : IEventMiddleware<MyEvent>
{
     private readonly ILogger<SampleEventLoggerMiddleware> _logger;

     public SampleEventLoggerMiddleware(ILogger<SampleEventLoggerMiddleware> logger)
     {
           _logger = logger;
     }

     public async Task Invoke(MyEvent @event, CancellationToken cancellationToken, NextMiddlewareDelegate next)
     {
          _logger.LogDebug("Event log: ", @event);

           //invoke the next middleware in the pipeline
           await next();
     }
}

Note

The NextMiddlewareDelegate next parameter is a delegate that encapsulates the call to the next element in the pipeline.

Event middleware pipeline

The following diagram demonstrates how middlewares are invoked under the hood.

../../_images/event_middleware_flow.png

Important

You have to invoke next to execute the next element in the pipeline. You can short circuit the pipeline simply don’t invoking next.