Вы используете все это неправильно. Во-первых, временные объекты времени жизни могут быть внедрены непосредственно в сервисы с определенной областью. Вы должны не вводить IServiceProvider
или IServiceScopeFactory
и т. Д., А скорее свои фактические зависимости. Вы уже внедряете свой контекст напрямую (это сервис с областью действия), поэтому я не уверен, почему вы пытаетесь обрабатывать что-то еще по-другому.
Вы должны вводить IServiceProvider
(ничего больше) только тогда, когда ваш объект имеет одноэтапное время жизни и нуждается в сервисах с областью действия. Это называется анти-паттерном сервисного локатора, и это анти-паттерн по причине: вы должны избегать необходимости делать это как можно больше. В общем, большинство из того, что люди считают синглетонами, на самом деле не должно быть синглетонами. Есть только несколько случаев, когда вам действительно нужна одиночная жизнь. Во всех других сценариях "scoped" должен быть вашим началом жизни. Кроме того, если вашему синглтону действительно нужны сервисы с областями действия, это сильный аргумент, что он должен быть сам по себе.
Однако, если вы делаете , попадаете в ситуацию, когда вам действительно нужно одноразовое время жизни и вам все еще нужны сервисы с определенной областью, то правильный способ сделать это следующий:
public class MySingletonService
{
private readonly IServiceProvider _provider;
public MySingletonService(IServiceProvider provider)
{
_provider = provider;
}
...
}
И это все. Вы не создаете область видимости внутри конструктора. Любая служба, извлеченная из области, существует только в этой области, и когда эта область исчезает, служба тоже. Таким образом, вы не можете сохранять сервисы с ограниченным диапазоном для ивара на одиночном. Вместо этого, внутри каждого отдельного метода, который нуждается в такой услуге, вам нужно сделать:
using (var scope = _provider.CreateScope())
{
var myScopedService = scope.ServiceProvider.GetRequiredService<MyScopedService>();
// do something with scoped service
}
Это еще одна причина, по которой сервисный локатор является анти-паттерном: он приводит к большому количеству тупого и повторяющегося кода. Иногда у вас нет выбора, но большую часть времени вы делаете.