![](/img/trans.png)
[英]How can a dependency (registered in nested LifetimeScope) be resolved from autofac container
[英]How can I resolve a registered Dependency from an Autofac Container in .NET Core 3.1
有一個項目我正在嘗試從 2.2 升級到 .NET Core 3.1。 我的主要問題是在 startup.cs 中,我正在向 Autofac 注冊依賴項。 我已經研究了在 3.0 中注冊依賴項的文檔並且我理解它。 但是ConfigureServices
方法要求將對象注冊為實例,並且它要求容器以與下面代碼中所示相同的方法解析注冊的服務
啟動.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);
}
在 .net core 3.1 中,我找不到使用新的 Autofac 方法復制上述內容的明確方法。
啟動 (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
方法之前執行,在那里我可以獲取對容器中已注冊依賴項的引用。 我似乎無法找到一種方法來從ConfigureServices
的容器解析IHttpContextAccessor
並像在 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();
}
}
}
您可以在Configure
執行以下Configure
盡管我不建議這樣做,因為您將在啟動的多個部分中注冊依賴項的責任分開。 這將通過IApplicationBuilder.GetServce<TService>()
解析 IHttpContextAccessor,然后您可以將其用於后續注冊。
public void Configure(IApplicationBuilder app, IHostEnvironment env)
{
var httpContextAccessor = app.ApplicationServices.GetService<IHttpContextAccessor>();
var executionContextAccessor = new ExecutionContextAccessor(httpContextAccessor);
var emailsConfiguration = new EmailsConfiguration(_configuration["EmailsConfiguration:FromEmail"]);
ModuleStartup.Initialize(executionContextAccessor, emailsConfiguration);
}
同樣,您也可以解析 IExecutionContextAccessor 以添加這樣的注冊。
public void Configure(IApplicationBuilder app, IHostEnvironment env)
{
var httpContextAccessor = app.ApplicationServices.GetService<IHttpContextAccessor>();
var executionContextAccessor = new ExecutionContextAccessor(httpContextAccessor);
var fooToRegister = new Foo(executionContextAccessor);
var registration = RegistrationBuilder
.ForDelegate<IAnotherInterface>((c, p) => fooToRegister)
.InstancePerLifetimeScope()
.CreateRegistration();
app.ApplicationServices
.GetAutofacRoot().ComponentRegistry
.Register(registration);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.