Consider the following code:
Startup.cs
```c#
public static void RegisterServices(IServiceCollection services)
{
services.AddSingleton
services.AddTransient
services.AddMediatR(typeof(AnsweredQuestionCommandHandler));
}
**RabbitMQBus.cs**
```c#
public sealed class RabbitMQBus : IEventBus
{
private readonly IMediator _mediator;
private readonly Dictionary<string, List<Type>> _handlers;
private readonly List<Type> _eventTypes;
private readonly IServiceScopeFactory _serviceScopeFactory;
public RabbitMQBus(IMediator mediator, IServiceScopeFactory serviceScopeFactory)
{
_mediator = mediator;
_serviceScopeFactory = serviceScopeFactory;
_handlers = new Dictionary<string, List<Type>>();
_eventTypes = new List<Type>();
}
public Task SendCommand<T>(T command) where T : Command
{
return _mediator.Send(command);
}
...
}
AnsweredQuestionCommandHandler.cs
```c#
public class AnsweredQuestionCommandHandler : IRequestHandler
{
private readonly IEventBus _bus;
private readonly IStuff _stuff;
public AnsweredQuestionCommandHandler(IEventBus bus, IStuff stuff)
{
_bus = bus;
_stuff = stuff;
}
...
}
```
Can someone explain why injecting a Stuff with Transient or Singleton lifetime works as expected--when SendCommand() is invoked, the constructor for AnsweredQuestionCommandHandler is called, Stuff is injected--but if inject it with Scoped lifetime, not only is Stuff never injected, but in fact the constructor for AnsweredQuestionCommandHandler is never even called when SendCommand() is invoked?
Ohhhh Singleton's can't depend on anything but Singleton or Transient. Anything a Singleton depends on is automatically elevated to Singelton.
In your code, don't inject an IMediator. Instead, use the IServiceScopeFactory to resolve a scope, and instantiate your IMediator from that scoped IServiceProvider.
This is exactly what ASP.NET Core does for each request:
Singletons can depend on Singletons
Scoped can depend on Singletons, Transients, and Scoped
Transients can depend on Singletons, Transients, and Scoped
Most helpful comment
Ohhhh Singleton's can't depend on anything but Singleton or Transient. Anything a Singleton depends on is automatically elevated to Singelton.
In your code, don't inject an
IMediator. Instead, use theIServiceScopeFactoryto resolve a scope, and instantiate yourIMediatorfrom that scopedIServiceProvider.This is exactly what ASP.NET Core does for each request:
https://github.com/aspnet/AspNetCore/blob/bae733151be352eed77c07dcdc13d87862a68477/src/Http/Http/src/Features/RequestServicesFeature.cs#L31
Singletons can depend on Singletons
Scoped can depend on Singletons, Transients, and Scoped
Transients can depend on Singletons, Transients, and Scoped