簡體   English   中英

如何從 .NET Core 3.1 中的 Autofac 容器解析已注冊的依賴項

[英]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在運行時拋出空引用。 我對此並不感到驚訝,因為ConfigureServicesConfigure方法之前執行,在那里我可以獲取對容器中已注冊依賴項的引用。 我似乎無法找到一種方法來從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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM