Вам нужно позвонить builder.Populate(services)
ДО того, как вы добавите вещи в контейнер для переопределения.
Если вы посмотрите в документах о том, как работает новый материал IServiceProviderFactory
, это в основном:
- Используйте
ConfigureServices
, чтобы зарегистрировать вещи с IServiceCollection
- За кулисами на фабрике поставщика услуг создается
ContainerBuilder
и для вас вызывается builder.Populate(services)
- Используйте
ConfigureContainer
для прямой регистрации в Autofac напрямую - За кулисами на заводе поставщика услуг создается конечный контейнер и помещается в
IServiceProvider
В более старой интеграции, где вы строите AutofacServiceProvider
самостоятельно, вы должны быть осторожны с порядком. Это все еще Autofac - последний в победах.
Когда вы делаете services.AddControllersAsServices()
, это все равно, что сказать builder.RegisterType<DataProcessController>().AsSelf()
... но на самом деле он еще не разговаривает со строителем. Это похоже на «сохраненную регистрацию», которая не будет «воспроизводиться» до тех пор, пока вы не позвоните Populate
.
Таким образом, если вы упростите свои регистрации и поместите вещи в порядок , они фактически выполнятся :
// These will NOT be executed until builder.Populate()
// services.AddOptions();
// services.AddHttpClient();
// services.AddMvc()
// .AddControllersAsServices()
// .SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
var builder = new ContainerBuilder();
builder.RegisterInstance(_logger).As<ILogger>().SingleInstance();
builder.RegisterType<DataProcessController>().AsSelf()
.WithParameter("ratio", 0.4);
// Still not executed until builder.Populate()
services.AddSwaggerExamplesFromAssemblyOf<Startup>();
// Here goes everything!
// - AddOptions => ContainerBuilder
// - AddHttpClient => ContainerBuilder
// - AddMvc => ContainerBuilder
// - AddControllersAsServices => ContainerBuilder
// ---- OH NO! JUST OVERWROTE THE WITHPARAMETER REGISTRATION!
// - AddSwaggerExamplesFromAssemblyOf => ContainerBuilder
builder.Populate(services);
return new AutofacServiceProvider(builder.Build());
Вот что я бы порекомендовал:
НАИЛУЧШИЙ ПРИМЕР: ПЕРЕМЕСТИТЬ ПОДДЕРЖКУ ФАБРИКИ ПРОВАЙДЕРА СЕРВИСА
В документации это тот, где в ASP.NET 1.1-2.2 вы сами не собираете AutofacServiceProvider и вместо этого регистрируете Autofac на уровне веб-хоста . Это лучший вариант, потому что он готовит вас к обновлению до ASP.NET Core 3.0, когда вы будете готовы. После того, как вы нажмете 3.0, вам все равно придется это сделать.
ПАРАМЕТР ОТДЫХА: ОРГАНИЗОВАТЬ РЕГИСТРАЦИИ
Если вы не можете переключить интеграцию, чтобы заставить вас использоватьразделите методы ConfigureServices
и ConfigureContainer
, хотя бы организуйте код в ConfigureServices
, чтобы вы были готовы. Это также гарантирует, что все будет вызвано в правильном порядке, чтобы избежать этой проблемы сейчас и в будущем.
- Сгруппируйте все
services.AddWhatever()
регистрации для IServiceCollection
вверху. Например, не позволяйте services.AddSwaggerExamplesFromAssembly
задерживаться среди регистраций Autofac. - Создайте
ContainerBuilder
и немедленно позвоните Populate
. Не помещайте никакие регистрации между этими двумя вещами. - Сгруппируйте все
builder.Register<T>()
регистрации с ContainerBuilder
после вызова builder.Populate
. - Оставьте создание поставщика услуг какАбсолютно последняя вещь в методе, как у вас сейчас.