Есть проект, который я пытаюсь обновить до. NET Core 3.1 с 2.2. Моя главная проблема - в файле startup.cs, где я регистрирую зависимости с помощью Autofa c. Я изучил документацию для регистрации зависимостей в 3.0, и я это понимаю. Но в методе ConfigureServices
есть требование зарегистрировать объект как экземпляр, и он требует, чтобы контейнер разрешил зарегистрированную службу тем же методом, как показано в приведенном ниже коде
Startup.cs ( 2.2)
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IExecutionContextAccessor, ExecutionContextAccessor>();
//other services registered
return CreateAutofacServiceProvider(services);
}
private IServiceProvider CreateAutofacServiceProvider(IServiceCollection services)
{
var containerBuilder = new ContainerBuilder();
containerBuilder.Populate(services);
containerBuilder.RegisterModule(new MyModule());
var container = containerBuilder.Build();
var httpContextAccessor = container.Resolve<IHttpContextAccessor>();
var executionContextAccessor = new ExecutionContextAccessor(httpContextAccessor);
var emailsConfiguration = new EmailsConfiguration(_configuration["EmailsConfiguration:FromEmail"]);
// executionContextAccessor is used to initialize some modules here
return new AutofacServiceProvider(container);
}
In. net core 3.1, я не смог найти четкого способа повторить вышесказанное с новым подходом Autofa c.
Запуск (3.1)
public ILifetimeScope AutofacContainer { get; private set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddSingleton<IExecutionContextAccessor, ExecutionContextAccessor>();
// other services registered
var httpContextAccessor = this.AutofacContainer.Resolve<IHttpContextAccessor>();
var executionContextAccessor = new ExecutionContextAccessor(httpContextAccessor);
var emailsConfiguration = new EmailsConfiguration(_configuration["EmailsConfiguration:FromEmail"]);
// executionContextAccessor is used to initialize some modules here
}
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder.RegisterModule(new MyModule());
}
public void Configure(IApplicationBuilder app, IHostEnvironment env)
{
this.AutofacContainer = app.ApplicationServices.GetAutofacRoot();
// other stuff
}
this.AutofacContainer
выбрасывает нулевую ссылку во время выполнения. Меня это не удивляет, потому что ConfigureServices
выполняется до метода Configure
, где я получаю ссылки на зарегистрированные зависимости в контейнере. Кажется, я не могу найти способ разрешить IHttpContextAccessor
из контейнера в ConfigureServices
и использовать его как есть в netcore 2.2.
Для ясности, пожалуйста, посмотрите, как executionContextAccessor
используется в класс, который выполняет инициализацию, как в netcoreapp2.2:
public class ModuleStartup
{
private static IContainer _container;
public static void Initialize(
IExecutionContextAccessor executionContextAccessor,
EmailsConfiguration emailsConfiguration)
{
ConfigureCompositionRoot(
executionContextAccessor,
emailsConfiguration);
}
private static void ConfigureCompositionRoot(
IExecutionContextAccessor executionContextAccessor,
EmailsConfiguration emailsConfiguration)
{
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterModule(new EmailModule(emailsConfiguration));
containerBuilder.RegisterInstance(executionContextAccessor);
_container = containerBuilder.Build();
ModuleCompositionRoot.SetContainer(_container);
}
Internal static class ModuleCompositionRoot
{
private static IContainer _container;
internal static void SetContainer(IContainer container)
{
_container = container;
}
internal static ILifetimeScope BeginLifetimeScope()
{
return _container.BeginLifetimeScope();
}
}
}