Полагаю, вы говорите об этом куске кода:
services.BuildServiceProvider(new ServiceProviderOptions
{
ValidateScopes = true
});
// or
services.BuildServiceProvider(true); // or false
Базовый поставщик ASP.NET имеет механизм, который проверяет, разрешается ли служба с определенными областями в одноэлементном контейнере. ASP.NET Core имеет два вида контейнеров. Основной одноэлементный контейнер, действительный в течение срока службы приложения, и контейнеры с областями действия для каждого запроса.
Этот параметр предотвратит разрешение служб с областью действия из одноэлементного контейнера, то есть если вы случайно попытаетесь разрешить службу с областью действия в методе Configure
, вы получите исключение. Принимая во внимание, что если вы отключите это, вы не должны.
public void Configure(IApplicationBuilder app)
{
// will throw exception, since by default DbContext is registered as scope
app.ApplicationServices.GetRequiredService<MyDbContext>();
}
Исключением является нечто похожее на
InvalidOperationException: Невозможно разрешить IExampleService от корневого поставщика, так как для него требуется служба с ограниченным доступом MyDbContext.
Такое поведение существует для предотвращения утечек памяти и разрешения служб с областью действия (которые должны быть недолговечными ) из одноэлементного контейнера, по существу делая эти службы также квази-синглетонами (потому что они не получат утилизируется до тех пор, пока контейнер не будет утилизирован, а контейнер-одиночка утилизируется только после закрытия приложения).
Правильный способ разрешения сервисов в пределах области действия, т. Е. Метод Configure
- это
// get scoped factory
var scopedFactory = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>();
// create a scope
using (var scope = scopedFactory.CreateScope())
{
// then resolve the services and execute it
var context = scope.ServiceProvider.GetRequiredService<MyDbContext>();
}
// here, the child (scoped) container will be disposed and all scoped and transient services from it
Значением по умолчанию является true
, и вы должны оставить его таким, если вы точно не знаете, что делаете, в противном случае вы рискуете получить утечку памяти (или исключение объекта, уже имеющего исключение) из-за невыпущенных сервисов.