var scopeFactory = services
.BuildServiceProvider()
.GetRequiredService<IServiceScopeFactory>();
Таким образом, вы создаете отдельного поставщика услуг и используете его услуги для получения фабрики области обслуживания.
Итак, когда вы позже сделаете следующее:
return (IValidator)scopeFactory.CreateScope().ServiceProvider.GetRequiredService(valType);
Вы используете этого отдельного поставщика услуг.И когда вы разрешаете услуги у этого поставщика услуг, они полностью отделены от тех, в которых ваше приложение выполняется.
И поскольку вы зарегистрировали Validator<Promotion>
only после , который вы создалиэтот отдельный поставщик услуг, этот поставщик услуг не будет включать вашу службу валидатора.
Как правило, не рекомендуется создавать несколько поставщиков услуг в одном приложении.Это просто приведет к тому, что службы будут иметь несколько жизненных циклов, например, у одного поставщика услуг будет один раз, и у вас возникнут проблемы, когда вы будете взаимодействовать с услугами других поставщиков (как, например, сейчас).Вместо этого вы должны попытаться решить вашу проблему, используя только одного поставщика услуг.
В вашем случае вы можете получить это, например, изменив регистрацию вашего поставщика услуг проверки:
services.AddSingleton<IValidationProvider>(sp =>
{
Func<Type, IValidator> validatorFactory = type =>
{
var valType = typeof(Validator<>).MakeGenericType(type);
return sp.GetRequiredService(valType);
};
return new ValidationProvider(validatorFactory);
});
sp
, который передается на завод, там есть поставщик услуг, один правильный.Таким образом, вы можете использовать это непосредственно для разрешения служб, необходимых для инициализации поставщика.
Вы заметите, что я не создаю новую область обслуживания в пределах validatorFactory
.Это связано с тем, что при использовании областей обслуживания вы должны всегда располагать ими после использования.Если вы просто создадите их и разрешите службу из них, тогда область обслуживания останется открытой, и вы можете столкнуться с проблемами позже.
В вашем случае вы не сможете правильно утилизировать область обслуживания, поскольку вам нужновернуть разрешенный объект и захотеть использовать его потом.Так что это означает, что использование области обслуживания здесь не очень хорошая идея.Вам также следует подумать о том, действительно ли вам нужна область обслуживания в целом: ASP.NET Core уже создает область обслуживания для каждого запроса, поэтому имеет смысл просто повторно использовать эту область, если вам действительно нужна зависимость по объему.
К сожалению, это также означает, что ваша реализация ValidationProvider
на самом деле не совместима с этим.Вы можете сделать ValidationProvider
самой службой с заданной областью, чтобы она могла безопасно получать доступ к службам с заданной областью от поставщика услуг (без необходимости управлять своей собственной областью обслуживания) или, если вам действительно нужно, чтобы она была одиночной, вы также могли бы переместить эту логикув саму реализацию провайдера валидации.