

It's a bit ugly, however, since we're forcing a base class into our request objects, breaking the concept of "favor composition over inheritance". Here we're placing the current request user onto an items dictionary on the request object, so that subsequent behaviors/processors can then use that user object. Request.Items = _httpContextAccessor.User => _httpContextAccessor = httpContextAccessor Public AuthBehavior(IHttpContextAccessor httpContextAccessor) Private readonly IHttpContextAccessor _httpContextAccessor


We use the request object as the object to place any shared context items, with any behavior then putting/removing items on it: public class AuthBehavior One option available to us is to simply hijack the request object through some sort of base class: public abstract class ContextualRequest Filters must explicitly use this context object for any kind of resolution of objects.įor each of our behaviors, we have either our request object, dependency injection, or service location available for us. Our behaviors take simply a request object, while these filters have some sort of context object. This looks similar to our behavior, except with the first parameter. Task OnActionExecutionAsync(ActionExecutingContext context, For example, an action filter: public interface IAsyncActionFilter : IFilterMetadata What are our options here? In ASP.NET Core, we have filters. Inevitably however, it becomes necessary to share information across behaviors/processors. Side note - it's possible to do functional patterns directly in C#, higher order functions, monads, partial application, currying, and more, but it's really, really ugly and not idiomatic C#. Task Process(TRequest request, TResponse response,īasically, I'm recreating a lot of existing functional patterns in an OO language, using dependency injection. Task Process(TRequest request, CancellationToken cancellationToken) Then on top of calling into a handler, we might want to call things around our handler for cross-cutting concerns, which led to behaviors: public interface IPipelineBehaviorįor simple scenarios, where I want to execute something just before or after a handler, MediatR includes a built-in pipeline behavior with additional pre/post-processors: public interface IRequestPreProcessor

Task Handle(TRequest request, CancellationToken cancellationToken) Once you adopt its pattern, you'll often find many other related patterns start to show up - decorators, chains of responsibility, pattern matching, and more.Įverything starts with a very basic implementation - a handler for a request: public interface IRequestHandler MediatR, a small library that implements the Mediator pattern, helps simplify scenarios when you want a simple in-memory request/response and notification implementation.
