0

Update:

The Mediatr in the project is used without any customized logic for dispatching the messages. Can I say it's used as an event aggregator?


In the source code of https://github.com/JasonGT/NorthwindTraders, the Controller gets the Mediator from ControllerBase.

[ApiController]
[Route("api/[controller]/[action]")]
public abstract class BaseController : ControllerBase
{
    private IMediator _mediator;

    protected IMediator Mediator => _mediator ??= HttpContext.RequestServices.GetService<IMediator>();
}

In the controller, it calls Mediator.Send(...) to send the message to the mediator.

public class EmployeesController : BaseController
{
    // ....
    [HttpGet("{id}")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    public async Task<ActionResult<EmployeeDetailVm>> Get(int id)
    {
        return Ok(await Mediator.Send(new GetEmployeeDetailQuery { Id = id }));
    }

And the method Handle() in the inner class GetEmployeeDetailQuery.GetEmployeeDetailQueryHandler will be called for query message GetEmployeeDetailQuery. How is this wired?

public class GetEmployeeDetailQuery : IRequest<EmployeeDetailVm>
{
    public int Id { get; set; }

    public class GetEmployeeDetailQueryHandler : IRequestHandler<GetEmployeeDetailQuery, EmployeeDetailVm>
    {
        private readonly INorthwindDbContext _context;
        private readonly IMapper _mapper;

        public GetEmployeeDetailQueryHandler(INorthwindDbContext context, IMapper mapper)
        {
            _context = context;
            _mapper = mapper;
        }

        public async Task<EmployeeDetailVm> Handle(GetEmployeeDetailQuery request, CancellationToken cancellationToken)
        {
            var vm = await _context.Employees
                .Where(e => e.EmployeeId == request.Id)
                .ProjectTo<EmployeeDetailVm>(_mapper.ConfigurationProvider)
                .SingleOrDefaultAsync(cancellationToken);

            return vm;
        }
    }
}
ca9163d9
  • 27,283
  • 64
  • 210
  • 413

1 Answers1

1

In the startup.cs of that project, there's a call to AddApplication, which is an extension method from the NorthwindTraders.Application project, and is defined in DependencyInjection.cs. This calls services.AddMediatR(Assembly.GetExecutingAssembly());, which scans the assembly for handlers and registers them.

In general, you can register MediatR for your own projects by calling services.AddMediatr(Assembly.GetExecutingAssembly()) in your web application's Startup.ConfigureServices method.

Jonathon Chase
  • 9,396
  • 21
  • 39
  • I guess `AddMediatR` registers them by `IRequest<...>` and `IRequestHandler`. Will it get error if the type parameters `EmployeeDetailVm` in `IRequest` and `IRequestHandler` are different? – ca9163d9 Oct 31 '19 at 20:45
  • BTW, the `Mediatr` in the project doesn't have any logic when dispatching the messages. Can I say it's used as an event aggregator? – ca9163d9 Oct 31 '19 at 20:52
  • 1
    @ca9163d9 An event aggregator is a good idea of what it is, but you may want to look at [this question](https://stackoverflow.com/questions/14456429/mediator-eventaggregator-differences) to see how it differs. There is actually logic applied during the dispatch in the form of MediatR 3's Pipelines, which can be used to intercept and perform operations on requests before they reach the handler. There are two registered pipeline behaviors in that project- one that is timing requests and one that is handling validation. – Jonathon Chase Oct 31 '19 at 20:56