【问题标题】:Using DI in ConfigureService-Methods (especially IApplicationLifetime) in .NET Core在 .NET Core 的 ConfigureService-Methods(尤其是 IApplicationLifetime)中使用 DI
【发布时间】:2017-09-24 19:17:12
【问题描述】:

我正在尝试为IWebHostBuilder 实现一个新的扩展方法,该方法执行一些代码,比如在某处注册。 重要的是,当应用程序关闭时它也会取消注册。

我添加了一些代码来显示我想要做什么。这里的问题是,IApplicationLifetime 的实例尚不可用。这种新的扩展方法是最后在构建 WebHost 的管道中添加的。

public static IWebHostBuilder UseHttpGatewayappRegistration(this IWebHostBuilder webHostBuilder)
    {
        webHostBuilder.ConfigureServices(services =>
        {
            var sp = services.BuildServiceProvider();

            // This instance is not available
            IApplicationLifetime applicationLifetime = sp.GetService<IApplicationLifetime>();

            // These instances are ok
            AppSettings appSettings = sp.GetService<AppSettings>();
            ILoggerFactory loggerFactory = sp.GetService<ILoggerFactory>();

            var registration = new Registration(loggerFactory.CreateLogger<Registration>());

            applicationLifetime.ApplicationStopping.Register(() =>
            {
                registration.Unregister();
            });
        });

        return webHostBuilder;
    }

为什么IApplicationLifetime 实例为空,即使我在构建 WebHost 管道的管道中最后添加了此扩展方法?如果有人能向我提供一些关于所有“ConfigureServices”方法的执行顺序以及如何或是否可以在ConfigureServices 方法中使用IApplicationLifetime 的信息,那就太好了。

我知道我可以在没有WebHostBuilder 的情况下完成这一切,但对我来说在那里这样做似乎是合乎逻辑的,我也认为必须有一种方法。

很遗憾,我在网上找不到太多信息...

谢谢。

编辑:我找到了一种在ConfigureServices 方法中使用DI 的方法。我相应地编辑了问题。这对我有帮助:How to Resolve Instance Inside ConfigureServices in ASP.NET Core

【问题讨论】:

    标签: c# asp.net-core .net-core


    【解决方案1】:

    您无法通过ConfigureServices 方法访问IApplicationLifetime 实例。这是设计使然。在此处检查“启动中可用的服务”部分: Application Startup in ASP.NET Core.

    IWebHostBuilder.Configure方法中解析IApplicationLifetime(如果稍后在IWebHostBuilder配置管道中使用,它会替换Startup.Configure方法):

    public static IWebHostBuilder Foo(this IWebHostBuilder webHostBuilder)
    {
        webHostBuilder.Configure(x =>
        {
            var service = x.ApplicationServices.GetService<IApplicationLifetime>();
        });
    
        return webHostBuilder;
    }
    

    也可以扩展原来的Startup.Configure方法而不是replace(应该添加很多反射逻辑来使这个解决方案可靠):

    .Configure(app =>
    {
        var env = app.ApplicationServices.GetService<IHostingEnvironment>();
        dynamic startup = Activator.CreateInstance(typeof(TStartup), env);
    
        //Carefully resolve all input parameters.
        //Make sure all required services are registered in DI.
        startup.Configure(app, env);
    
        var lifetime = app.ApplicationServices.GetService<IApplicationLifetime>();
    })
    

    【讨论】:

    • 嗯,好的,谢谢...我已经尝试过使用Configure 方法。问题是,我还并行使用了Startup 类,所以当我在扩展方法中调用Configure 方法时,不再调用Startup 类中的Configure 方法...跨度>
    • @timothy3001,我想在Configure方法中注册服务是不可能的。因此,即使我们手动创建一个Startup 实例并从Configure 调用Startup.ConfigureServices,它也不会成功。可能最好将扩展方法重新设计为 IApplicationBuilder 扩展,如下所示:stackoverflow.com/a/43610530/5112433
    • 好的,谢谢。我真的不需要在Configure 方法中注册服务,而是在ConfigureServices 方法中使用IApplicationLifetime 来获得关闭挂钩。我将它放入Startup 的问题是,我认为它不属于那里。它与 HTTP 管道的设置无关。但由于目前没有其他选择,我会继续这样做。谢谢
    • @timothy3001,我已经添加了原始Startup.Configure 方法的示例,该方法扩展而无法替换。也许会有所帮助。感谢您提出有趣的问题。
    • 哦,哇,非常感谢 :) 这在我看来是“最干净”的解决方案。
    猜你喜欢
    • 2021-04-14
    • 2017-07-28
    • 1970-01-01
    • 2023-03-17
    • 2021-08-23
    • 2018-10-26
    • 2021-03-04
    • 2023-03-08
    • 2021-08-13
    相关资源
    最近更新 更多