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

标签 asp.net-core dependency-injection mediatr

我收到以下错误:

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

尝试调用_mediator.Send方法时。

只有当我尝试测试 Controller 的方法时才会发生这种情况。每当从 api 调用 Controller 时,它似乎工作得很好。

Controller :

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());

我正在尝试使用真实的数据库连接来测试此 Controller 。

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());

我不确定后果。

最佳答案

在“使用”结束时,范围被处置。 当您将此“中介者”返回给 Controller 时,范围将被释放并且“中介者”无法访问。 尝试在您想要使用的地方解析“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);
}

关于asp.net-core - 在测试中使用 MediatR 时无法访问已处置的对象 (IServiceProvider),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68016905/

相关文章:

symfony - 装饰所有默认实现相同接口(interface)的服务?

java - 无需实现接口(interface)即可提供 OSGi 服务

c# - DependencyInjectionConfig 中的 MediatR 问题与 Autofac

.net - 如何在 .NET Core 中使用默认依赖注入(inject)从父级创建子范围?

authentication - 发送用户 ID 和 access_token

c# - asp.net 5 自定义类中的依赖注入(inject),正确的方法是什么?

c# - 通过 MediatR PipelineBehavior 进行单元测试验证

asp.net-web-api2 - CQRS ValidatorHandler 无法识别 FluentValidation 验证器?

c# - 将左列添加到 MVC Net Core 元素模板 View 中,该 View 会随着用户向下滚动而消失

asp.net-mvc - 在 ASP.NET Core 1.1 中配置基本身份验证中间件