Tackling cross-cutting concerns with a mediator pipeline

Originally posted on the Skills Matter website

In most of the projects I’ve worked on in the last several years, I’ve put in place a mediator to manage the delivery of messages to handlers. I’ve covered the motivation behind such a pattern in the past, where it works well and where it doesn’t.

One of the advantages behind the mediator pattern is that it allows the application code to define a pipeline of activities for requests, as opposed to embedding this pipeline in other frameworks such as Rails, node.js, ASP.NET Web API and so on. These frameworks have many other concerns going on besides the very simple “one model in, one model out” pattern that so greatly simplifies conceptualizing the system and realizing more powerful patterns.

As a review, a mediator encapsulates how a series of objects interact. Our mediator looks like:

public interface IMediator
{
    TResponse Send<TResponse>(IRequest<TResponse> request);
    Task<TResponse> SendAsync<TResponse>(IAsyncRequest<TResponse> request);
    void Publish<TNotification>(TNotification notification) where TNotification : INotification;
    Task PublishAsync<TNotification>(TNotification notification) where TNotification : IAsyncNotification;
}

This is from a simple library (MediatR) I created (and borrowed heavily from others) that enables basic message passing. It facilitates loose coupling between how a series of objects interact. And like many OO patterns, it exists because of missing features in the language. In other functional languages, passing messages to handlers is accomplished with features like pattern matching.

Our handler interface represents the ability to take an input, perform work, and return some output:

public interface IRequestHandler<in TRequest, out TResponse>
    where TRequest : IRequest<TResponse>
{
    TResponse Handle(TRequest message);
}

With this simple pattern, we encapsulate the work being done to transform input to output in a single method. Any complexities around this work are encapsulated, and any refactorings are isolated to this one method. As systems become more complex, isolating side-effects becomes critical for maintaining overall speed of delivery and minimizing risk.

We still have the need for cross-cutting concerns, and we’d rather not pollute our handlers with this work.

These surrounding behaviors become implementations of the decorator pattern. Since we have a uniform interface of inputs and outputs, building decorators around cross-cutting concerns becomes trivial.

Pre- and post-request handlers

One common request I see is to do work on the requests coming in, or post-process the request on the way out. We can define some interfaces around this:

public interface IPreRequestHandler<in TRequest> {
    void Handle(TRequest request);
}

public interface IPostRequestHandler<in TRequest, in TResponse> {
    void Handle(TRequest request, TResponse response);
}

With this, we can modify inputs before they arrive to the main handler or modify responses on the way out.

In order to execute these handlers, we just need to define a decorator around our main handler:

public class MediatorPipeline<TRequest, TResponse> 
    : IRequestHandler<TRequest, TResponse> 
    where TRequest : IRequest<TResponse> {

    private readonly IRequestHandler<TRequest, TResponse> _inner;
    private readonly IPreRequestHandler<TRequest>[] _preRequestHandlers;
    private readonly IPostRequestHandler<TRequest, TResponse>[] _postRequestHandlers;

    public MediatorPipeline(
        IRequestHandler<TRequest, TResponse> inner,
        IPreRequestHandler<TRequest>[] preRequestHandlers,
        IPostRequestHandler<TRequest, TResponse>[] postRequestHandlers
        ) {
        _inner = inner;
        _preRequestHandlers = preRequestHandlers;
        _postRequestHandlers = postRequestHandlers;
    }

    public TResponse Handle(TRequest message) {

        foreach (var preRequestHandler in _preRequestHandlers) {
            preRequestHandler.Handle(message);
        }

        var result = _inner.Handle(message);

        foreach (var postRequestHandler in _postRequestHandlers) {
            postRequestHandler.Handle(message, result);
        }

        return result;
    }
}

And if we’re using a modern IoC container (StructureMap in this case), registering our decorator is as simple as:

cfg.For(typeof (IRequestHandler<,>))
   .DecorateAllWith(typeof (MediatorPipeline<,>));

When our mediator builds out the handler, it delegates to our container to do so. Our container builds the inner handler, then surrounds the handler with additional work. If this seems familiar, many modern web frameworks like koa include a similar construct using continuation passing to define a pipeline for requests. However, since our pipeline is defined in our application layer, we don’t have to deal with things like HTTP headers, content negotiation and so on.

Validation

Most validation frameworks I use validate against a type, whether it’s validation with attributes or delegated validation to a handler. With Fluent Validation, we get a very simple interface representing validating an input:

public interface IValidator<in T> {
    ValidationResult Validate(T instance);
}

Fluent Validation defines base classes for validators for a variety of scenarios:

public class CreateCustomerValidator: AbstractValidator<CreateCustomer> {
  public CreateCustomerValidator() {
    RuleFor(customer => customer.Surname).NotEmpty();
    RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Please specify a first name");
    RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
    RuleFor(customer => customer.Address).Length(20, 250);
    RuleFor(customer => customer.Postcode).Must(BeAValidPostcode).WithMessage("Please specify a valid postcode");
  }

  private bool BeAValidPostcode(string postcode) {
    // custom postcode validating logic goes here
  }
}

We can then plug our validation to the pipeline as occurring before the main work to be done:

public class ValidatorHandler<TRequest, TResponse>
    : IRequestHandler<TRequest, TResponse>
    where TRequest : IRequest<TResponse> {

    private readonly IRequestHandler<TRequest, TResponse> _inner;
    private readonly IValidator<TRequest>[] _validators;
    
    public ValidatorHandler(IRequestHandler<TRequest, TResponse> inner,
        IValidator<TRequest>[] validators) {
        _inner = inner;
        _validators = validators;
    }

   public TResponse Handle(TRequest request) {
        var context = new ValidationContext(message);

        var failures = _validators
            .Select(v => v.Validate(context))
            .SelectMany(result => result.Errors)
            .Where(f => f != null)
            .ToList();

        if (failures.Any()) 
            throw new ValidationException(failures);

        return _inner.Handle(request);
   }
}

In our validation handler, we perform validation against Fluent Validation by loading up all of the matching validators. Because we have generic variance in C#, we can rely on the container to inject all validators for all matching types (base classes and interfaces). Having validators around messages means we can remove validation from our entities, and into contextual actions from a task-oriented UI.

Framework-less pipeline

We can now push a number of concerns into our application code instead of embedded as framework extensions. This includes things like:

  • Validation
  • Pre/post processing
  • Authorization
  • Logging
  • Auditing
  • Event dispatching
  • Notifications
  • Unit of work/transactions

Pretty much anything you’d consider to use a Filter in ASP.NET or Rails that’s more concerned with application-level behavior and not framework/transport specific concerns would work as a decorator in our handlers.

Once we have this approach set up, we can define our application pipeline as a series of decorators around handlers:

var handlerType = cfg.For(typeof (IRequestHandler<,>));

handlerType.DecorateAllWith(typeof (LoggingHandler<,>));
handlerType.DecorateAllWith(typeof (AuthorizationHandler<,>));
handlerType.DecorateAllWith(typeof (ValidatorHandler<,>));
handlerType.DecorateAllWith(typeof (PipelineHandler<,>));

Since this code is not dependent on frameworks or HTTP requests, it’s easy for us to build up a request, send it through the pipeline, and verify a response:

var handler = container.GetInstance<IHandler<CreateCustomer>>();

var request = new CreateCustomer {
    Name = "Bob"
};

var response = handler.Handle(request);

response.CreatedCustomer.Name.ShouldBe(request.Name);

Or if we just want one handler, we can test that one implementation in isolation, it’s really up to us.

By focusing on a uniform interface of one model in, one model out, we can define a series of patterns on top of that single interface for a variety of cross-cutting concerns. Our behaviors become less coupled on a framework and more focused on the real work being done.

All of this would be a bit easier if the underlying language supported this behavior. Since many don’t, we rely instead of translating these functional paradigms to OO patterns with IoC containers containing our glue.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in Architecture, Design, DomainDrivenDesign. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Would you hydrate your domain entities using an “IHydrateEntitiesHandler” as one of the first steps? Your TResponse classes, how would you handle all of the difference types of errors; validation, domain errors, invalid entity id’s etc…?

    • What purpose would “hydration” serve?

      • If you were executing a TRequest from a MVC controller for example you would have a model which needed the entities to be loaded from the DB before “handling” the request on them.

    • jbogard

      First question, no. That’d just be in the core handler. In my responses, I don’t include errors on it. Those are just done through an exception and I include a filter to then handle it at the MVC level. All validation is done through fluent validation, so I don’t have multiple levels of validation.

      • Say you were on a user admin screen changing the selected “Favourite Colour”. How do you validate that their selection of Favourite Colour (id=6 for example) exists as a colour to pick in the DB? By your answer I assume you check this in the “core handler” instead of in the “ValidationHandler” as you need to check the DB to see if ID 6 exists? Or do you allow DB access in your validation handlers? What about if you need to hydrate a “User” object to get permissions before checking those in the “SecurityHandler”? You may end up having database access scattered throughout your Handler chain which may, or may not be a good thing.

        • jbogard

          Yep, with fluent validation I get an IValidator that’s supplied by the container – and therefore take a dependency on ISession/DbContext etc.

          For security, I tend to put this up at the UI level (plays nicer with MVC etc.) with an attribute. That way my link builders can detect the permission and hide buttons/links you don’t have access to, and MVC then can perform authorization as needed. An attribute, being metadata, is a bit easier to work with for those varied scenarios.

          • Doesn’t that approach cause performance issues when you have a LOT of ad-hoc ISession/DBContent access scattered all throughout your Handler chain? The more complex the TRequest is the more problematic the Data Access becomes.

          • jbogard

            Not that we’ve seen, since ISession includes a first-level cache. If things get crazy, we’ll go ahead and pull in all the data we need to validate in one go. But it’s kinda nice to have all the validation for a single request in one spot.

  • Beyers

    For anyone interested in this subject I highly recommend you read the following two posts by Steven aka .NET Junkie

    https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91
    https://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92

  • Patrick

    On my current project I’ve basically implemented the identical set of abstractions and interactions, even down to the usage of FluentValidation. Rocky Lhotka used to talk about decoupling your business logic from UI and DataAccess technologies, because they change so frequently. I have a similar feeling towards hosting technologies; there seems to be an explosion in this space right now, so making your stack host-agnostic (as much as possible) seems like a no-brainer.

    One notable difference… I started off with a decorator approach to modeling the cross-cutting concerns, but when looking at stacktraces, or setting a breakpoint in the inner-most Handler(TResponse), the wall of text felt overwhelming at times. I ended up mimicking the decorator interaction, but using a queue (things to start), stack (things that started and need to end) and iterator (get next thing). The result was a pluggable decoration pipeline (GetAllInstances from container), but implemented as a sequence so the callstack was always digestible.

    Thanks for another good post.

    • jbogard

      I think the cool thing about this pattern is you could just build *one* decorator that includes your app-specific pipeline (pre-process, validation, handler, post-process etc).

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1691()

  • Phil Cleveland

    For a pre-request that does authentication, how would you get the credentials into the command? Do you put the name, pass, and claims on the command itself? If so, that seems a little unelegant. I will have to do something like var identity = Request.GetBasicIdentity(); on every controller method in order to build up the command. Hope there is a nicer way of doing this and I am just being dense. Cheers

    • jbogard

      I usually just use a dependency, something like IUserContext whose implementation goes out to HttpContext etc. I try to make the commands the user input and not secondary information that can be retrieved from contextual places.

  • For the last code sample “container.GetInstance<IHandler>()”, what is IHandler? I can’t seem to find a reference to it in the rest of the article.

  • Jim

    Jimmy, how is Mediatr compared to ShortBus performance wise?

    • jbogard

      No clue. All of my handlers have to hit a DB or web service, so that time dwarfs anything else.

    • Aaron

      Just from looking at the code, I would say MediatR would have to easily outperform Shortbus. ShortBus uses reflection to find, and invoke the handler method, where as MediatR does some smarts with generics and an private wrapper class which completely avoids doing any reflectiony method invoking. I think it still does an Activator.CreateInstance on the small private wrapper class, but that is not *that* slow, nor is it anywhere near as slow (or brittle) as doing a bunch of reflection to find the method, then invoke it.

      • Matt H

        This isn’t true. The activator.createinstance call is more expensive (in my benchmarks) than the method lookup. That’s why I changed it to use that technique in the first place. (see the original shortbus first commit: https://github.com/mhinze/ShortBus/blob/3ffb9026842c07750ba510a0e4bcfb7761d6518d/ShortBus/Bus.cs#L77) After .NET 4.5 all reflection is much faster so it’s less consequential.

        • Aaron

          Just ran a quick benchmark and you’re right, ShortBus takes almost 3 seconds for a million calls and MediatR takes just over 4 seconds. I’m guessing the performance penalty is not so much due to the Activator.CreateInstance call per se, but the cost of newing up an extra class vs not newing up a class. Having said that though, I’d have to agree with Jimmy’s comment below: the cost of the mediator’s handle invocation implementation being completely dwarfed by almost anything any given handler would actually do. Give those numbers – a million calls taking MediatR just over 4 seconds vs ShortBus taking just under 3 seconds – I think I’d prefer not to be making dynamic method calls unless I *really* have to. Although in this case it’s not like that method is going anywhere or changing, so my reasoning isn’t totally rational…

          • jbogard

            All my MediatR calls hit a database or a web service, so every call is at least 10ms. MediatR’s overhead of reflection is a fraction of a fraction of a percent of a request. Meh.

          • Aaron

            While I wouldn’t say *all* my calls hit dbs etc, I do agree that discussing the performance difference between the two is completely meaningless given how lightweight they both are, which was pretty much my point to Matt. I only responded originally based on a quick eyeballing over the code, and I saw dynamic method calls in one and not in the other. Intuition took over from there.

          • Matt H

            I came back to mention this is a great post and I use MediatR today on my current project – my choice! =D

          • 250,000 req/s and 333,333 req/s, that’s validation that architecturally the choice is sound. once you hook in any form of IO, your req/s will all drop atleast 2 zeros, for many it will drop 3, and for the ugly it will drop 4 zeros.

  • Phil Lee

    Hi Jimmy,
    I love the way this allows one to focus the logic for a given business action into a single handler, and also split various cross-cutting concerns out into their own decorators – superb! One thing I’m not sure about is how this fits with your two previous articles on refactoring controllers and get/query vs edit/command handlers etc.
    If you were using MediatR on an MVC project, would you still define separate IQuery/ICommand & IQueryHandler/ICommandHandler interfaces (in conjunction with a mediators such as shortbus), or does your IRequestHandler defined in the MediatR project supercede these?
    Thanks,
    Phil

    • jbogard

      Yep it does!

  • RyanVice

    I can’t see the code samples on this post or the linked one using chrome. Is it just me?

  • Phil Lee

    Hi Jimmy,
    I’m up & running with the Nuget package & it’s working well now using IRequest for Commands/queries to do single operations (e.g. save customer record to database). When it comes to multiple operations (e.g. save customer to database, then send email) how (and at what point) should I inject a decorator? Should I have a single command that handles saving the record and sending the email, or two commands/handlers, where the first saves the record to the database, then sends a new command to the Mediatr for dispatch to the second handler? The reason I ask is that if there are two commands involved, the second (send email) should only be called if the first succeeds, and I’m not sure how best to wire them together.
    Thanks,
    Phil

  • Pingback: MediatR hits 1.0 | Jimmy Bogard's Blog()

  • notmyself

    For anyone looking for how to accomplish this, here is how I was able to get the mediator pipeline registered using the Autofac container builder.

    builder.RegisterGenericDecorator(typeof (MediatorPipeline), typeof (IRequestHandler), “MediatorPipeline”);

    Has anyone implemented an async pipeline yet? I took a stab at it yesterday and got lost on the generic constraint bunny trail. Might try again later this week.

    @jbogard:disqus do you use pipelines to manage UoW/Transactions? Also, how do you fail a command in the pre processor stage? Is throwing an exception the only solution?

    • notmyself

      I was successful in creating an async mediator pipeline yesterday. Here is a gist with the code and associated autofac registration.

      https://gist.github.com/NotMyself/579f94e1aad6a022ddb9

      • John Kattenhorn

        This looks really interesting and perfect for something I’m struggling with right now – Thanks for sharing.

  • Kev Hunter

    Has anyone managed to get this working with Ninject? Try as I might I can’t find any easy way for it to handle decorators properly

  • Pingback: Generic variance in DI containers | Jimmy Bogard's Blog()

  • Andre

    Hi Jimmy,

    Great post.

    I am trying to implement this pattern in my app and came across an issue with Autofac not decorating my handlers correctly. When I try to resolve my decorator via Autofac, I do get a valid instance of the handler, however I see no pre/pos/validation handlers attached (count = 0). On the other hand, if I instantiate my objects manually, it’s all good.

    Images 1 and 2 are for your reference.

    Thanks
    Andre

    • Andre

      Found the solution below on @notmyself:disqus answer that I had overlooked for some reason !

      Thanks :)

  • Brandon Mikeska

    Do you have an example on how to do this with Rails?

    • jbogard

      Nope, sorry!

      • Brandon Mikeska

        Yeah I have been looking everywhere. I don’t know how to use this in a dynamic language. When working in C# it’s really nice to create this vertical pipeline, and I want to try and use it say in Rails or Meteor, but having a tough time wrapping it around my head how it could work.

        Thanks for answering quickly!

        • jbogard

          Ah, dynamic languages is a different question! Rails is its own beast with so much baked in that are difficult to move away from. In JavaScript I use hash tables to functions, or even a chain of responsibility pattern (isMatch checks metadata on the object).

          • Brandon Mikeska

            Ah that looks like a good route to go. Thank you a ton!

  • Andre Gallo

    How would you go about using the mediator pipeline in a complex system where one would have to check many tables to see whether a user has the permission to perform an action? I’ll give you an example:

    “a user wants to download a track”.

    For this simple request, I’d have to check whether this track can be downloaded – this would involve a number of queries in a number of different tables. I can see two solutions here:

    1. You use your normal DownloadTrackRequestHandler and execute a sql query which contains all joins and checks (complex query). This gives yous the benefit of a single DB round trip. However, your security check (rules) are embedded on your DB and I don’t quite like that.

    2. You use a DownloadTrackPreRequestHandler or a DownloadRequestAuthorizationHandler to check on the permission for that track. This might involve a lot of DB queries (expensive), however, your code is totally object oriented and easy to understand and more importantly easy to test!

    Any advice would be great.

  • Andrey Karavaychik

    Am I right saying that we should create validator over TRequest?
    var context = new ValidationContext(message); What is message? Is it typo?

  • Andrey Karavaychik

    What if I want to have ValidatorHandler for both IRequest and IAsyncRequest? What is the best approach to avoid code duplication?

    • jbogard

      Don’t use IRequest in that case.

      • Andrey Karavaychik

        ok, thank you

      • Ron Buchanan

        If we have both Async and Sync processing though in the app wouldn’t we need to implement both a ValidatorHandler and ValidatorAsyncHandler?

        • jbogard

          Just make everything async in that case.

  • Ron Buchanan

    Great article, but how would you do the this type of DI with Unity? Not such a friendly syntax as Structure Map :)

    • jbogard

      Not sure, perhaps SO has some answers?

      • Ron Buchanan

        Thanks for answering. BTW, I love Mediatr, some really nice work there. I am unfortunately stuck with Unity :/. To your Q…

        It does, but not necessarily around this exact situation. I can get Unity to wire things up for the decorator, but Unity seems to require everything to be named in this scenario.

        For instance, this is the DI for an auditor decorator.


        Container.RegisterType(typeof(ICommandAuditor),
        typeof(DefaultCommandAuditor),
        "DefaultCommandAuditor");

        Container.RegisterType(typeof(ICommandHandler),
        typeof(DefaultCommandAuditHandler),
        "DefaultCommandAuditHandler",
        new InjectionConstructor(
        new ResolvedParameter(typeof(ICommandHandler), "DefaultPipeline"),
        new ResolvedParameter(typeof(ICommandAuditor), "DefaultCommandAuditor")
        ));

        How does mediatr handle that when trying to get a handler if it needs a name?

  • jungle_mole

    how is it not tasks, where Rx begging to use itself?

    • jbogard

      How is what not tasks?

  • Dustin Hodges

    Nice article and thanks for sharing but there is a problem. You are talking about building a Mediator Pipeline by defining Pre/Post handlers and even define some interfaces for them but then the code samples don’t use the pipeline, they just decorate MediatR’s IRequestHandler. This is a little confusing. Overall though, very helpful and I got my pipeline set up in no time. Thanks!

  • Brian Potocki

    I’m curious, how do you prefer to expose enough information for the actual execution environment to act on? For example, if you have a ‘GetPerson(int personId)’ command, but the personId doesn’t exist and you want the web environment to return a 404 status.

    Does the web environment watch for specific exception types, or do you like to return that information in the command result?

  • c_windsor

    Anyone know how to do this in Castle Windsor:

    cfg.For(typeof (IRequestHandler))

    .DecorateAllWith(typeof (MediatorPipeline));

    • jbogard

      GH issue?

  • Tengiz Tutisani

    I think this is an anti-pattern specifically for commands, while it fits better into event handling patterns. I’m amazed by how many anti-patterns I keep finding which people love…
    Why in the world would I ask a “command” to be handled without me knowing the exact interface (pass in command as request, get response, act on it if needed)? if you just think about it for a second, command is something that needs to be handled in very concrete manner, by very specific and always single handler. Then what’s the benefit of abstracting the handling away? ah I see, we love reflection so much that we stick it everywhere!
    Anyway, for “event”, this pattern would make more sence, since usually event handling is something that originator does not care about – fire and forget. Single event may be handled by several destinations, and it almost always “does not matter” who and how exactly handles it, and in which order.

    • jbogard

      The benefit is a uniform interface that everything flows through. You don’t have to invent services etc or have a controller depend on 5 handlers.
      Just off the top of my head.

    • Why on Earth this is an anti-pattern? What about commands being sent via a message bus? You only share a contract and transport. Always assuming that sender of the command knows how it will be handled is a far call, introduces synchronous coupling. We went away from MediatR with commands but certainly it has “only one handler” IRequestHandler interface unlike INotificationHandler, which is a fanout publish. Also when calling Send or SendAsync you always get an exception when there is no handler, unlike Publish and PublishAsync. It is just a conventional messaging but in-process, without any bus.

      • Tengiz Tutisani

        Message bus is just an infrastructure and transport between communication boundaries. It’s just a consequence of the implementation that commands are sent somewhat similar to events (through message bus and through wire – there is no other way other than “fire and forget” in this case), but that does not mean that conceptually command stands close to event. Command is something that implies the originator wants it handled; while event has already happened in the past, and the originator just informed the world, without forcing anybody to handle it in any way.
        So, if we could draw a line between a concept and an implementation (which I think we should), concept should express a “command sending” as a regular method call on a specific interface (representing a handler for this specific command), and the implementation should handle it in whatever the way it’s implemented (e.g. through message bus, or through in-memory queues – just an implementation detail).
        On the other hand, for events, concept and implementation stand close to each other, if we consider message bus as an implementation – both they denote “fire and forget” – so it’s ok to express it as an interface which just takes any kind of event and dispatches it (or maybe not even that, at least that’s not the originator’s concern anyway).

        • jbogard

          In any case, I don’t see the code smell. It’s very similar to message passing, with a command message, plus the benefit of a uniform interface that makes testing suuuuuper easy.

          Inside the handler you can absolutely hand off to the domain model. Or not, the originator doesn’t care, which makes it easy to work with from the outer layer of the app. It’s worked great for us anyway for the past….seven years now?

          • Tengiz Tutisani

            Oh, I don’t want to argue (again). What you are presenting as a benefit, has many drawbacks to it – so you are a good seller, emphasize on benefits, make everyone forget about problems…
            Unit testing is easy but same is true for the alternative – if you just inject a specific handler interface into the originator. There is no much (if any at all) difference from unit testing standpoint, except you need to define one interface for each originator, and that is not a big deal.
            Besides, let’s talk about the hidden problem behind your super easy unit testing now: how do you ensure that unit-test covers everything that the caller does? e.g. imagine caller sent your expected command (hence the unit test passed), and also after or before that sent another unexpected command. Your unit test will pass but it’s brittle – you can change functionality in the originator, and unit test does not fail as long as it receives the expected command. With specific interface injection, you are providing a caller only a “limited interface for interaction”, which makes unit tests stricter, and keeps caller more under control. As I said, in case of events, who cares how many other events the originator dispatches, so this problem is not relevant. But for commands – I sure do want to know what exactly is happening inside the originator.
            Now, I know you can also setup your dispatcher interface mock not to accept any command other than the expected, but then your unit tests are not “suuuper” easy anymore. Explicit interfaces are much better also conceptually, so I don’t really see any benefit with your approach for commands.

          • jbogard

            I don’t think I actually understand what you’re arguing _for_. Maybe a blog post? This for example came from a series of posts on “put your controllers on a diet”, where I de-factored a complicated DDD solution full of repositories and services, into a flatter, entirely consistent structure. My assumptions and pains were all laid out there, but my assumptions and pains certainly might not have been the same you see.

          • The handler-class pattern has been described f.ex. by Greg Young back in 2010 http://codebetter.com/gregyoung/2010/07/12/command-handlers-and-the-domain-model/ and is working well ever since. It allows easy decoupling and removes the need for lazy instantiation of multiple dependencies in case we are in the same endpoint. Your points are hard to grasp, especially the story with expected vs “unexpected” commands. It would be nice to see some examples.

  • Has anyone been able to set up a pipeline in ASP.NET Core yet? @notmyself:disqus’s Gist https://gist.github.com/NotMyself/579f94e1aad6a022ddb9 doesn’t seem to work in the StartUp class for ASP.NET Core

    • jbogard

      I’m releasing MediatR 3 soon that has the pipeline stuff built in.