I'm getting following error:
Cannot access a disposed object.
Object name: 'IServiceProvider'.
When trying to call _mediator.Send
method.
This happens only when i'm tryign to test controller's method. Whenever controller is called from api it seems to work jsut fine.
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);
}
}
}
RequestHandler:
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 is registered this way:
services.AddMediatR(Assembly.GetExecutingAssembly());
I'm trying to test this controller with real db connection.
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);
The only way to solve the problem is to register MediatR as singleton:
services.AddMediatR(mediatRServiceConfiguration => mediatRServiceConfiguration.AsSingleton(), Assembly.GetExecutingAssembly());
I'm not sure about consequences.
At the end of the "using", the scope was disposed. when you returned this 'mediator' to the Controller, the scope is disposed and 'mediator' is unreachable. try to resolve 'mediator' in where you want to use that
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);
}