CQRS with MediatR and AutoMapper

CQRS is a simple pattern – two objects for command/queries where once there was one. These days just about every system I build utilizes CQRS, as it’s a natural progression from refactoring your apps around the patterns arising from reads and writes. I’ve been refactoring a Microsoft sample app to techniques I use on my apps (mainly because I want something public to look at for new projects) at my github.

Remember, CQRS is not an architecture, it’s a pattern, which makes it very easy to introduce into your applications. You can use CQRS in some, most, or all of your application and it’s easy to move towards or away from.

Even in simple apps, I like to keep my read models separate from my write models, mainly because the demands for each are drastically different. Since CQRS is just a pattern, we can introduce it just by refactoring.

First, let’s look at refactoring a complex GET/read scenario.

Read model

My initial controller action for a complex read is…well, complex:

public ViewResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
    ViewBag.CurrentSort = sortOrder;
    ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
    ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";

    if (searchString != null)
    {
        page = 1;
    }
    else
    {
        searchString = currentFilter;
    }

    ViewBag.CurrentFilter = searchString;

    var students = from s in db.Students
                   select s;
    if (!String.IsNullOrEmpty(searchString))
    {
        students = students.Where(s => s.LastName.ToUpper().Contains(searchString.ToUpper())
                               || s.FirstMidName.ToUpper().Contains(searchString.ToUpper()));
    }
    switch (sortOrder)
    {
        case "name_desc":
            students = students.OrderByDescending(s => s.LastName);
            break;
        case "Date":
            students = students.OrderBy(s => s.EnrollmentDate);
            break;
        case "date_desc":
            students = students.OrderByDescending(s => s.EnrollmentDate);
            break;
        default:  // Name ascending 
            students = students.OrderBy(s => s.LastName);
            break;
    }

    int pageSize = 3;
    int pageNumber = (page ?? 1);
    return View(students.ToPagedList(pageNumber, pageSize));
}

In order to derive our read models, I center around building query objects and result objects. The Query model represents the “inputs” to the query and the Result model represents the “outputs” from the query. This also fits very well into the “one-model-in-one-model-out” concept I use in my apps these days.

Looking at our controller, the inputs are pretty obvious – it’s the parameters to the controller action!

public class Index
{
    public class Query : IRequest<Result>
    {
        public string SortOrder { get; set; }
        public string CurrentFilter { get; set; }
        public string SearchString { get; set; }
        public int? Page { get; set; }
    }

To make my life easier with this pattern, I’ll use MediatR as a simple means of providing a way to have “one model in goes to something to get one model out” without creating bloated service layers. Uniform interfaces are great!

The next piece I need are the output – the result. I take *all* the results, including those “ViewBag” pieces as the Result object from my query:

public class Result
{
    public string CurrentSort { get; set; }
    public string NameSortParm { get; set; }
    public string DateSortParm { get; set; }
    public string CurrentFilter { get; set; }
    public string SearchString { get; set; }

    public IPagedList<Model> Results { get; set; }
}

public class Model
{
    public int ID { get; set; }
    [Display(Name = "First Name")]
    public string FirstMidName { get; set; }
    public string LastName { get; set; }
    public DateTime EnrollmentDate { get; set; }
}

Finally, I take the inside part of that controller action and place it in a handler that takes in a Query and returns a Result:

public class QueryHandler : IRequestHandler<Query, Result>
{
    private readonly SchoolContext _db;

    public QueryHandler(SchoolContext db)
    {
        _db = db;
    }

    public Result Handle(Query message)
    {
        var model = new Result
        {
            CurrentSort = message.SortOrder,
            NameSortParm = String.IsNullOrEmpty(message.SortOrder) ? "name_desc" : "",
            DateSortParm = message.SortOrder == "Date" ? "date_desc" : "Date",
        };

        if (message.SearchString != null)
        {
            message.Page = 1;
        }
        else
        {
            message.SearchString = message.CurrentFilter;
        }

        model.CurrentFilter = message.SearchString;
        model.SearchString = message.SearchString;

        var students = from s in _db.Students
                       select s;
        if (!String.IsNullOrEmpty(message.SearchString))
        {
            students = students.Where(s => s.LastName.Contains(message.SearchString)
                                           || s.FirstMidName.Contains(message.SearchString));
        }
        switch (message.SortOrder)
        {
            case "name_desc":
                students = students.OrderByDescending(s => s.LastName);
                break;
            case "Date":
                students = students.OrderBy(s => s.EnrollmentDate);
                break;
            case "date_desc":
                students = students.OrderByDescending(s => s.EnrollmentDate);
                break;
            default: // Name ascending 
                students = students.OrderBy(s => s.LastName);
                break;
        }

        int pageSize = 3;
        int pageNumber = (message.Page ?? 1);
        model.Results = students.ProjectToPagedList<Model>(pageNumber, pageSize);

        return model;
    }
}

My handler now completely encapsulates the work to take the input and build the output, making it very easy to test the logic of my system. I can refactor the contents of this handler as much as I want and the external interface remains input/output. In fact, if I wanted to make this a view or stored procedure, my input/output and tests don’t change at all!

One slight change was to switch to AutoMapper projection at the bottom with the ProjectToPagedList method:

public static class MapperExtensions
{
    public static async Task<List<TDestination>> ProjectToListAsync<TDestination>(this IQueryable queryable)
    {
        return await queryable.ProjectTo<TDestination>().DecompileAsync().ToListAsync();
    }

    public static IQueryable<TDestination> ProjectToQueryable<TDestination>(this IQueryable queryable)
    {
        return queryable.ProjectTo<TDestination>().Decompile();
    }

    public static IPagedList<TDestination> ProjectToPagedList<TDestination>(this IQueryable queryable, int pageNumber, int pageSize)
    {
        return queryable.ProjectTo<TDestination>().Decompile().ToPagedList(pageNumber, pageSize);
    }

    public static async Task<TDestination> ProjectToSingleOrDefaultAsync<TDestination>(this IQueryable queryable)
    {
        return await queryable.ProjectTo<TDestination>().DecompileAsync().SingleOrDefaultAsync();
    }
}

I build a few helper methods to project from a queryable to my read model. The AutoMapper projections completely bypass my write model and craft a query that only reads in the information I need for this screen:

exec sp_executesql N'SELECT 
    [Project1].[C1] AS [C1], 
    [Project1].[ID] AS [ID], 
    [Project1].[LastName] AS [LastName], 
    [Project1].[FirstName] AS [FirstName], 
    [Project1].[EnrollmentDate] AS [EnrollmentDate]
    FROM ( SELECT 
        [Extent1].[ID] AS [ID], 
        [Extent1].[LastName] AS [LastName], 
        [Extent1].[FirstName] AS [FirstName], 
        [Extent1].[EnrollmentDate] AS [EnrollmentDate], 
        ''0X0X'' AS [C1]
        FROM [dbo].[Person] AS [Extent1]
        WHERE ([Extent1].[Discriminator] = N''Student'') AND ((( CAST(CHARINDEX(UPPER(@p__linq__0), UPPER([Extent1].[LastName])) AS int)) > 0) OR (( CAST(CHARINDEX(UPPER(@p__linq__1), UPPER([Extent1].[FirstName])) AS int)) > 0))
    )  AS [Project1]
    ORDER BY [Project1].[LastName] ASC
    OFFSET 3 ROWS FETCH NEXT 3 ROWS ONLY ',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=N'a',@p__linq__1=N'a'

Some folks prefer to create SQL Views for their “Read” models, but that seems like a lot of work. AutoMapper projections have the same concept of a SQL View, except it’s defined as a projected C# class instead of a SQL statement with joins. The result is the same, except I now define the projection once (in my read model) instead of twice in my model and in a SQL view.

My controller action becomes quite a bit slimmed down as a result:

public ViewResult Index(Index.Query query)
{
    var model = _mediator.Send(query);

    return View(model);
}

Slimmed down to the point where my controller action is really just a placeholder for defining a route (though helpful when my actions do more interesting things like Toastr popups etc).

Now that we’ve handled reads, what about writes?

Write models

Write models tend to be a bit easier, however, many of my write models tend to have a read component to them. The page with the form of data is still a GET, even if it’s followed by a POST. This means that I have some duality between GET/POST actions, and they’re a bit intertwined. That’s OK – I can still handle that with MediatR. First, let’s look at what we’re trying to refactor:

public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Student student = db.Students.Find(id);
    if (student == null)
    {
        return HttpNotFound();
    }
    return View(student);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "ID, LastName, FirstMidName, EnrollmentDate")]Student student)
{
    try
    {
        if (ModelState.IsValid)
        {
            db.Entry(student).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
    catch (RetryLimitExceededException /* dex */)
    {
        //Log the error (uncomment dex variable name and add a line here to write a log.
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
    }
    return View(student);
}

Ah, the notorious “Bind” attribute with magical request binding to entities. Let’s not do that. First, I need to build the models for the GET side, knowing that the result is going to be my command. I create an input for the GET action with the POST model being my result:

public class Query : IAsyncRequest<Command>
{
    public int? Id { get; set; }
}

public class QueryValidator : AbstractValidator<Query>
{
    public QueryValidator()
    {
        RuleFor(m => m.Id).NotNull();
    }
}

public class Command : IAsyncRequest
{
    public int ID { get; set; }
    public string LastName { get; set; }

    [Display(Name = "First Name")]
    public string FirstMidName { get; set; }

    public DateTime? EnrollmentDate { get; set; }
}

One nice side effect of building around queries/commands is it’s easy to layer on tools like FluentValidation. The command itself is based on exactly what information is needed to process the command, and nothing more. My views are built around this model, projected from the database as needed:

public class QueryHandler : IAsyncRequestHandler<Query, Command>
{
    private readonly SchoolContext _db;

    public QueryHandler(SchoolContext db)
    {
        _db = db;
    }

    public async Task<Command> Handle(Query message)
    {
        return await _db.Students
            .Where(s => s.ID == message.Id)
            .ProjectToSingleOrDefaultAsync<Command>();
    }
}

Again, I skip the write model and go straight to SQL to project to my write model’s read side.

Finally, for the POST, I just need to build out the handler for the command:

public class CommandHandler : AsyncRequestHandler<Command>
{
    private readonly SchoolContext _db;

    public CommandHandler(SchoolContext db)
    {
        _db = db;
    }

    protected override async Task HandleCore(Command message)
    {
        var student = await _db.Students.FindAsync(message.ID);

        Mapper.Map(message, student);
    }
}

Okay so this command handler is very, very simple. Simple enough I can use AutoMapper to map values back in. Most of the time in my systems, they’re not so simple. Approving invoices, notifying downstream systems, keeping invariants satisfied. Unfortunately Contoso University is a simple application, but I could have something more complex like updating course credits:

public class CommandHandler : IAsyncRequestHandler<Command, int>
{
    private readonly SchoolContext _db;
 
    public CommandHandler(SchoolContext db)
    {
        _db = db;
    }
 
    public async Task<int> HandleCore(Command message)
    {
        var rowsAffected = await _db.Database
            .ExecuteSqlCommandAsync("UPDATE Course SET Credits = Credits * {0}", message.Multiplier);
 
        return rowsAffected;
    }
}

I have no idea why I’d need to do this action, but you get the idea. However complex my write side becomes, it’s scoped to this. In fact, I can often refactor my domain model to handle its own command handling:

public class CommandHandler : AsyncRequestHandler<Command>
{
    private readonly SchoolContext _db;
 
    public CommandHandler(SchoolContext db)
    {
        _db = db;
    }
 
    protected override async Task HandleCore(Command message)
    {
        var student = await _db.Students.FindAsync(message.ID);
 
        student.Handle(message);
    }
}

All the logic in processing the command is inside my domain model, fully encapsulated and unit-testable. My handler just acts as a means to get the domain model out of the persistent store. The advantage to my command handler now is that I can refactor towards a fully encapsulated, behavioral domain model without changing anything else in my application. My controller is none the wiser:

public async Task<ActionResult> Edit(Edit.Query query)
{
    var model = await _mediator.SendAsync(query);

    return View(model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(Edit.Command command)
{
    await _mediator.SendAsync(command);

    return this.RedirectToActionJson(c => c.Index(null));
}

That’s why I don’t worry too much about behavioral models up front – it’s just a refactoring exercise when I see code smells pop up inside my command handlers. When command handlers get gnarly (NOT BEFORE), just push the behavior down to the domain objects as needed using decades-old refactoring techniques.

That’s it! MediatR and AutoMapper together to help refactor towards CQRS, encapsulating logic and behavior together into command/query objects and handlers. Our domain model on the read side merely becomes a means to derive projections, just as Views are means to build SQL projections. We have a common interface with one model in, one model out to center around and any cross-cutting concerns like validation can be defined around those models.

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, AutoMapper, CQRS, MediatR. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Jim

    I’ve taken to having my Query/Command and it’s handler in the same file, but not within another class, just namespaced. Any reason why to have them within another class? eg the Create class here: https://github.com/jbogard/ContosoUniversity/blob/master/src/ContosoUniversity/Features/Course/Create.cs

    • jbogard

      Something I’m trying on some projects where I see a bunch of files, and some places that have rules around “only one class per file”. There’s not too much difference otherwise, “Index.Query” vs “IndexQuery” or “ApproveCommand” vs “Approve.Command”.

    • notmyself

      I have been doing this as well, I have even extended MediatR to use Pre and Post handlers well. Here is an example of one of my command files. One of the things that I have started doing is just handing along the ModelState as part of my command. This way anywhere along the handler chain can add a message and kick the form back to the user for correction. I can have simple unobtrusive validations happening live on the client and more complex data dependent validations happening server side.

      https://gist.github.com/NotMyself/515ad816c441d51ad81e

      • jbogard

        Nice! Yeah I’ve seen a few folks doing that as well – returning generic result objects instead of everything one-off.

        • notmyself

          Yeah I like it quite a bit so far. I have yet to get a really complicated command going yet, but they are coming soon. I feel a bit weird about passing the model state like that, but it seems to work nicely. Are you aware of any concerns I should have about doing so?

          • jbogard

            Yeah, well your only other option is to move validation into the pipeline with IValidator (and is why I like to use FluentValidation)

          • notmyself

            Yeah the only reason I am not using it is I am trying to limit the scope of what the guy I have to hand this off to has to learn. MediatR is already going to blow his mind. 8)

  • Mathieu Lafontaine

    As always, great article. Looking forward to share that with my teammates.

  • Really clear summary and illustration of the benefits, thanks. I learnt a lot from your earlier series of posts on this subject which influenced how I’m building applications these days.

    One extension I used to the pattern was finding a way to continue to use the ASP.Net validation framework (with data annotations etc.) on my view models, but then if valid, map to a command for then passing to the handler. Details here if interested: http://web-matters.blogspot.it/2014/08/cqrs-with-aspnet-mvc-entity-framework.html – I’d certainly be keen to hear any feedback on the approach.

    • jbogard

      Sure! You know, I go back and forth myself. I would love to use data annotations for the simple scenarios, but “graduate” to the more full-featured validation frameworks as needed. I haven’t had success in using both yet, however.

  • Marek Benes

    Jimmy, thanks for another fantastic article! I have a few questions though.

    1) What’s typically in your domain entities? Does they contain some behavior or is all the logic inside handlers?
    2) If you need to use other queries/commands (or more generally, any ‘shared’ logic) from within some handler how do you do that? Do you user mediator interface or e.g. via some kind of domain service, or so?

    • jbogard

      1) Sometimes they’re just persistence models, sometimes they’re domain models. The logic in the handlers and refactoring pushes them one way or the other. I don’t really care one way or the other.
      2) Standard refactoring or another mediator call. Sometimes I just do Compose Method (cause honestly it’s just a single procedure in a handler).

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

  • Chuck Bryan

    Jimmy, I’ve been using this pattern for a bit now. Great article. I especially liked the FluentValidator example. Also, AM Project().To is awesome. I sometimes get tripped up using this when I want to format a DateTime to String. Can I still use ProjectTo, or, do I need to fall back to doing this formatting somewhere else in the pipeline?

    • jbogard

      What version of AutoMapper are you using?

      • Chuck Bryan

        The project is using 3.2.1

        • Alex Gill

          See https://github.com/AutoMapper/AutoMapper/issues/691 – suggested workaround is to have two properties in your viewmodel (one DateTime, one string) and then use ToString() when you are out of IQueryable

        • jbogard

          ToString should be supported, have you tried writing a Select LINQ projection manually to see what happens? This might be a GH issue.

          • Chuck Bryan

            I apologize, I think I should have said ToShortDateString is Linq To Entity can’t translate. However, Alex’s response demonstrated the Each() to mutate the properties. That is such an obvious answer that I am slapping my forehead right now. Slap.

  • I built something internally almost identical to MediatR and have been trying to figure out how best to use it. I ended up with a lot of objects and handlers, with handlers that in turn call the mediator and use other handlers. The separation of code was nice, but I think it comes with a loss of cohesion as well.

    It seems like the more you head towards this model the more you might as well go to a fully functional approach.

    What I’d like to see is an example involving nested MediatR calls and external services that need to percolate errors back to the UI.

  • cocowalla

    Any chance of uploading a complete sample project to GitHub?

    • jbogard

      Yeah it’s that link in the first paragraph.

      • cocowalla

        Ah, sorry, don’t know how I missed that!

  • Shayne van Asperen

    Looks great, except that in the original implementation, you were returning a BadRequest (400) when the id was null, and a NotFound (404) when the student could not be found in persistent storage. Now in the final implementation, you always return a view with status code of 200 (and sometimes the model could be null, which the view would need to be able to deal with).

    This is where I think MediatR falls down – it makes flow control (if, else, switch) hard to achieve cleanly. There is not always one model in and one model out: depending on input scenario, the output should be either a status code result or a view result. You could of course use the lowest common denominator of ActionResult, but then you are simply writing in the handler what would have been in the controller in the first place and you’d need to pass the ControllerContext into the handler – very messy.

    • jbogard

      Just create your own result, CommandResult or the like. I just didn’t want to bake that result object in, it’s easy enough to do yourself. We’ve done this on a couple of projects and it’s worked out fine.

      You could still handle 404 too, and 400 if they didn’t pass in an ID or a bad ID with validation if you like. Or a richer result not tied to MVC, whatever.

      • Shayne van Asperen

        Okay, but then you need to write code to convert from CommandResult to ActionResult in the controller, which essentially repeats the if-else which is in the handler. Not very DRY at all then.

        • jbogard

          Honestly, this really hasn’t come up for me. I generally avoid a wrapped result and use action filters to handle the other scenarios as a cross cutting concern. They’re pretty easy to handle that way.

          If my controller action doesn’t fit into the one model in/out paradigm like PDF results etc then I don’t use MediatR. If duplicated controller action logic can be handled with filters I’ll use that. Validation, 404 etc fit in that category.

          • Shayne van Asperen

            If you’re using an action filter to check for a 404 (given id is not in database) then your action filter would need to query for the database record and if it does exist in the database, you have to throw it away, only to then query for it again in the command handler, thus incurring an extra hit on the database.

          • jbogard

            So check for a null result just like the controller action did originally? The way I see it, you have two places to enforce a common pipeline: inside the mediator or outside. Standard rules of “what to do with the duplication” still apply.

            Either way, I try to have *one* spot where my policy is applied and not copy that 404 logic in every single controller action.

          • Shayne van Asperen

            You say: “So check for a null result just like the controller action did originally”. What I’m saying is that by doing so you end up querying the database twice (once in the action filter, and then again in the command handler). And don’t tell me that the solution to that is to just cache it.

            Also, how would you propose to have a generic 404 action filter when the parameter names and entity types that need to be queried for would be different across different action methods?

            The bottom line here is that your refactored “edit” controller action has regressed on functionality that used to work (400 and 404). If you’re going to write a blog post to demonstrate a pattern, then you should ensure that it is complete and accurate.

          • jbogard

            I took it out because, honestly, the app is contrived anyway. It’s for illustrative purposes. You could use any of a half-dozen strategies that only query once.

            I also took out that retry strategy stuff. It’s only really used in Azure situations. Also easily achieved as a cross-cutting concern.

            I try not to get too specific here because folks like to take these and just copy-paste code – that’s not the point. The point is you have many options, pick what works best for your cross-cutting concern.

          • Shayne van Asperen

            This is why I hate contrived examples. Excuse me if I’m being a little thick here, but I’m really struggling to see how one would implement this so that you only queried once. You say that there are a half-dozen strategies, but I can’t even think of one. Would you mind showing just *one* of those you have in mind?

          • jbogard

            Inside your handler, if result == null throw new EntityNotFoundException. Then have an exception filter.

  • Dariusz Lenartowicz

    Hi Jimmy, great sum-up of usability of MediatR. I’m using it for a while but have question. Are you using MR sending requests in chain (call Send one from another)? In other words are you using it in internal calls instead of bloated classes called ‘services’?

    • jbogard

      I try to avoid chained requests as much as possible, unless it’s in a scenario where a command returns the result of the command in the form of updated state (common in REST).

  • Hossam Barakat

    Very good article that simplify CQRS.
    I have question, Isn’t having a return type from the command against CQRS, and makes it difficult to scale the system, because you will not be able to have true asynchronous commands?

    • jbogard

      No, it’s not against CQRS. No, it doesn’t make it difficult to scale the system. You can get a very, very, very long way without going async. Unless the processing is already very long, then I would look at saga patterns.

      • Hossam Barakat

        Would you guide me why it is not against CQRS.

        • jbogard

          Your command handler could invoke the read handler – in fact this is very common in REST scenarios. Requests return the new state.

          • Hossam Barakat

            But I thought that in REST the API handler create command object to change the state which shouldn’t return value, then the API handler can query for the state through the read model.

          • jbogard

            Nope, there’s nothing that says you can’t in the HTTP spec. In fact, a PUT can return state, see https://tools.ietf.org/html/rfc7231#section-4.3.3

  • Dave

    Is there a difference between CQRS and CQS? I thought CQRS had 2 databases – 1 for reads and 1 for writes. They’d then sync up at regular intervals. I thought CQS was more akin to what you’ve done here. Or is that just a pedantic distinction? Either way, a well-written, informative post. I use a similar thing in my apps. Mediator enables an onion architecture.

    • jbogard

      CQRS is not “2 databases”. CQRS is just 2 objects for read/write where once there was one. CQS is about methods being either queries or commands – returning state or mutating state but not both. It’s not pedantic – they’re two different things.

      • Dave

        OK, thanks. Sometimes these distinctions are lost on me. Until someone shakes me like an English nanny and says “They’re different!”. Cheers.

  • Timothy Elvidge

    You can teach an old dog new tricks. Last Christmas I worked through Jimmy’s articles on CQRS and the Mediator pattern. Wow!! It has completely revolutionized the way I write my MVC projects. I struggled with the immutability of Mediator interfaces as most of my code uses Generics and finally came up with some classes and interfaces that for me anyway make it a bit clearer what is going on https://gist.github.com/tim-elvidge/e9832448a3cddfc60adc

  • kd

    Jimmy, with this pattern, how do you go about re-using/sharing logic in Queries/Commands? For example, if you had a command handler that created a student, and another command handler that created a course, and then a student in the exact same way, how would you re-use your create student logic in this pattern?

    • I would like to offer my view on this. I understand that you want some re-use because the code for creating a Student without a course might be exactly the same as the code for creating a Student with a course.

      But is their sameness fundamental or accidental? In terms of the code, they might be the same (same class, same properties, same dbset, etc) but in terms of the business concept, they might actually be different (if only a little). So I’d say that their sameness is only accidental.

      In cases like this (where the sameness is only in the code but not really in the business concept), I would tend not to attempt to re-use. As some people smarter than me have said, “duplication is far cheaper than the wrong abstraction”.

      A more common example of this is in Create/Edit activities. Their implementations are very similar so things tend to get shared, like the ViewModel, the code (“Upsert”), the actual View, the JavaScript, etc. But I believe that this is another “accidental” case and thus I would tend not to attempt re-use here as well.

      Disclaimer: for all of my recommendations, there is also a silent, unspoken “it depends” :)

      Feel free to comment (whether positive or negative). We are all learning so I appreciate any feedback!

      • jbogard

        Good question – it’s the same in *this* application, but in general, not.

  • Pure joy. love it!

  • Arturo Ribes

    Thanks for such instructive article, I really like the pattern and I see myself introducing it in my next application, at least gradually.
    I access my entities through service objects, inheriting a generic DataService which provides CRUD methods. This base service contains logic for restricting the data operations depeding on the access rights of the current user.

    In a CQRS approach, would you (a) inject an IDataService into the query/command handlers or (b) would the query/command handlers BE the IDataService? If (a), then my query/command handlers are just transforming query/commands to service object calls, and if (b), then you would have to implement base handlers to “decorate” the queries with access right related query/command criteria (query customers of a particular user, assigning the userId to the newly created customer).

  • Josh Noe

    Thanks for this, but please don’t use contrived class names like “Query”, “Result”, and “Command” in your examples. It makes the example much harder to follow. I guess I shouldn’t look a gift horse in the mouth, but just some feedback :) .

    • jbogard

      What would you rather them be named? I followed my convention of Controller.Action.MessageType, so Query is really Home.Index.Query, Home.Index.Result etc.

  • Pravir Raghu

    Good day Mr Bogard, I have a question regarding the pattern of which I am currently enjoying using. However, I have come across, not so much an issue but rather something that I could learn from.
    How would one consume an ASP Web API service that makes use of Request(Query) and Response(Result) – Web API that implements MediatR – that can be strongly typed to class instances? To Simplify, if I have a Request Model in my web API that “passes” data to my handler, would a view model in a project such as a standard ASP MVC project need to follow the same structure; for example: if the Request model (or a Query in this case) is being passed to the handler and has a property of an ID of type integer, would the front end client application that has a view model need to follow the same structure of the request being pushed through; in that the view model in mention should also have a property of an ID that is of type integer, and in doing so won’t this result in replication of code? (the view model trying to match up with the query/request).

    • jbogard

      Could you open a GH issue for this? This looks like a good question that others might want an answer to.

      • Pravir Raghu

        Sure thing :)

  • Eirik Mangseth

    Jimmy, any experience with using Mediatr with Xamarin Forms apps? Do they play nicely together? Any gotcha’s one should look out for?

  • Fahimeh

    Hi Jimmy.
    We are using MediatR and AutoMapper similar to this post in our project, we also use AutoFac, and EF code first for db sets, could you please post a sample on how you can test the Mediator send or sendAsync in Unit test, also example on command and query testing?.
    I’m using XUnit and Moq for testing MediatR.
    But I am not sure how to mock the db, db queries or even mock the models mapped with AutoMapper

  • k3nn c.p.

    beginner in unity + mediatr here :D –> need to know exactly how
    to set up MediatR with Unity. can you show the wiring how to define
    container.Register() for the handlers in your example. I’ve tried it on
    my own using unity (the same with the example of “PONG” request/response
    from your wiki) but have run into runtime error:

    Resolution of the dependency failed, type = “MediatR.IRequestHandler`2[ReqMediatR,System.Boolean]“, name = “(none)”.
    Exception occurred while: while resolving.
    Exception
    is: InvalidOperationException – The current type,
    MediatR.IRequestHandler`2[ReqMediatR,System.Boolean], is an interface
    and cannot be constructed. Are you missing a type mapping?

    where:
    ReqMediatR is equivalent to RegisterUser class as they are both derived
    from IRequest. The point where it failed is in the code
    _mediator.send(reqMediatR) as I seem to think it cannot find the handler
    I defined in Unity. my unity registerTypes look like this:

    #region Mediatr
    container.RegisterType();
    container.RegisterTypes(AllClasses.FromLoadedAssemblies());

    container.RegisterTypes(AllClasses.FromAssemblies(typeof(ReqMediatR).Assembly),
    WithMappings.FromAllInterfaces, GetRequestName, GetLifetimeManager);
    container.RegisterInstance(t => container.Resolve(t));
    container.RegisterInstance(t => container.ResolveAll(t));
    #endregion
    ….
    #region Mediatr
    static bool IsNotificationHandler(Type type)
    {

    return type.GetInterfaces().Any(x => x.IsGenericType
    && (x.GetGenericTypeDefinition() ==
    typeof(INotificationHandler) || x.GetGenericTypeDefinition() ==
    typeof(IAsyncNotificationHandler)));
    }

    static bool IsRequestHandler(Type type)
    {

    return type.GetInterfaces().Any(x => x.IsGenericType
    && (x.GetGenericTypeDefinition() ==
    typeof(IRequestHandler) || x.GetGenericTypeDefinition() ==
    typeof(IAsyncRequestHandler)));
    }

    static LifetimeManager GetLifetimeManager(Type type)
    {
    return IsNotificationHandler(type) ? new ContainerControlledLifetimeManager() : null;
    }

    static string GetNotificationName(Type type)
    {
    return IsNotificationHandler(type) ? string.Format(“HandlerFor” + type.Name) : string.Empty;
    }
    static string GetRequestName(Type type)
    {
    return IsRequestHandler(type) ? string.Format(“HandlerFor” + type.Name) : string.Empty;
    }
    #endregion

    it is a bit long, but one more clue was that the debug line pointed to where the error was:

    container.RegisterInstance(t => container.Resolve(t));

    can you help how I can properly register my request handlers in unity? thanks for any info you may have.

    • jbogard

      Does the sample project inside the solution not work?

  • JordiR

    Hello Jimmy,

    In the post https://lostechies.com/jimmybogard/2009/09/18/the-case-for-two-way-mapping-in-automapper/ you said that it’s not good to use automapper to map between dto’s to entities, but I’m confused after viewing the Microsoft Sample app that you’re refactoring. When you create a course in the handler is:

    protected override void HandleCore(Command message)
    {
    var course = _mapper.Map(message);

    _db.Courses.Add(course);
    }

    It’s correct in CQRS world to automap the command directly to the entity? or it’s better to map manually?

    Thanks!

    • jbogard

      Most of my real apps are quite a bit more complex than this. In practice, it’s not as feasible.