在测试中使用 MediatR 时无法访问已处置的对象 (IServiceProvider)

Cannot access a disposed object (IServiceProvider) while using MediatR in tests

我收到以下错误:

Cannot access a disposed object.
Object name: 'IServiceProvider'.

尝试调用 _mediator.Send 方法时。

只有当我尝试测试控制器的方法时才会发生这种情况。每当从 api 调用控制器时,它似乎工作正常。

控制器:

public class Controller : ControllerBase
{
    private readonly IMediator mediator;
    public Controller(IMediator mediator)
    {
        this.mediator = mediator;
    }

    [HttpPost]
    public async Task<IActionResult> Post(Command command)
    {
        try
        {
            await mediator.Send(command); // exception occurs here
            return Ok();

        }
        catch (Exception ex)
        {
            return BadRequest(ex.InnerException?.Message ?? ex.Message);
        }
    }
}

请求处理程序:

  public class CommandHandler
    : IRequestHandler<Command, bool>
    {
        private readonly AppDbContext dbContext;
        public CommandHandler(AppDbContext dbContext)
        {
            this.dbContext = dbContext;
        }
        public async Task<bool> Handle(Command request, CancellationToken cancellationToken)
        {
            try
            {
                await dbContext.Companies.AddAsync(new Company(request.CompanyId, request.CompanyName), cancellationToken);
                await dbContext.SaveChangesAsync(cancellationToken);
                return true;
            }
            catch(Exception)
            {
                throw;
            }
        }
    }

MediatR 是这样注册的:

services.AddMediatR(Assembly.GetExecutingAssembly());

我正在尝试使用真实数据库连接测试此控制器。

protected Controller GetController() // method where controller is created and mediatR injected
{
    using var scope = _scopeFactory.CreateScope();
    var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
    return new Controller(mediator);
}



protected async Task<IActionResult> PostControllerMethod(Command command) // this method is call in test method
    => await GetController().Post(command);

解决问题的唯一方法是将MediatR注册为单例:

   services.AddMediatR(mediatRServiceConfiguration => mediatRServiceConfiguration.AsSingleton(), Assembly.GetExecutingAssembly());

我不确定后果。

在“using”结束时,作用域被释放。 当您将此 'mediator' 返回给 Controller 时,范围已被释放并且 'mediator' 无法访问。 尝试在你想使用的地方解析 'mediator'

protected Controller GetController() // method where controller is created and mediatR injected
{
    using var scope = _scopeFactory.CreateScope();
    var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
    return new Controller(mediator);
}