概要
1. Console App Demo
2. Web API + MediatR Demo
Console App Demo
简单的Console App Demo,包括使用自建的中介者对象实现以及MediatR实现
Web API + MediatR Demo
在WebAPI中使用MediatR,最大的改变是将原本注入到controller的依赖分散到了MediatR消息的处理方法中
传统的依赖注入如下图
使用MediatR后,MediatR作为抽象的一层将依赖进一步根据具体逻辑分散
而接口则变得非常简洁,即
1.发送MediatR消息
2.获得结果
3.返回结果
在MediatR消息的处理方法中,当然也可以通过注入MediatR来再次发送消息,即嵌套的调用。最大程度得分离逻辑来降低逻辑上的耦合
...
using MediatR;
using Application.Exceptions;
using Application.Item.Models;
using Data.RepositoryInterfaces;
using Domain.BaseInterfaces;
using Domain.Entities;
namespace WebApp.Controllers
{
[ApiController]
public class ItemController : ControllerBase
{
private readonly IMediator _mediator;
public ItemController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet]
[Route("")]
public async Task<ActionResult> Get(int itemId)
{
var result = await _mediator.Send(new GetItem(id, userid));
if (result == null) return NotFound();
return Ok(result);
}
}
}
namespace Application.Item.Queries
{
public class GetItem : IRequest<ItemViewModel>
{
public GetItem(int itemId, string userId)
{
UserId = userId;
ItemId = itemId;
}
public string UserId { get; }
public int ItemId { get; }
}
public class GetItemHandler : IRequestHandler<GetItem, ItemViewModel>
{
private readonly IMediator _mediator;
private readonly IItemRepository _itemRepository;
public GetItemHandler(
IMediator mediator,
IItemRepository itemRepository
)
{
_mediator = mediator;
_itemRepository = itemRepository;
}
public async Task<ItemViewModel> Handle(GetItem arg, CancellationToken cancellationToken)
{
var item = await _itemRepository.Get()
.Where(i => i.Id == arg.ItemId)
.Select(i => new
{
Id = i.Id,
Name = i.Name,
}).SingleOrDefaultAsync();
if (item == null)
throw new NotFoundException(arg.ItemId.ToString(), nameof(Domain.Entities.Item));
var companyUser = await _mediator.Send(new GetCompanyUser(arg.UserId, item.CompanyId));
bool isCompanyUser = companyUser != null;
return new ItemViewModel(){
ItemId = item.Id,
ItemName = item.Name,
IsCompanyUser = isCompanyUser
};
}
}
public class GetItemPreProcessor : IRequestPreProcessor<GetItem>
{
private readonly IMediator _mediator;
public GetItemPreProcessor(
IMediator mediator)
{
_mediator = mediator;
}
public Task<ItemViewModel> Process(GetItem request, CancellationToken cancellationToken)
{
return await _mediator.Send(new InsertItemViewRecord(request));
}
}
}
namespace Application.Item.Commands
{
//implement InsertItemViewRecord
}
Demo主要流程如下图