我应该在ASP.NET Core中的哪里执行自定义应用程序初始化步骤?

mls*_*lst 4 c# asp.net-core

ASP.NET Core框架为我们提供了两个定义明确的初始化位置:1 Startup.ConfigureServices().注册DI服务的Startup.Configure()方法2. 中间件管道的配置方法

但是,其他针对我的Web应用程序的初始化步骤又如何呢?它们应该去哪儿,特别是如果它们需要注入依赖项时?

例如,我需要根据配置文件appsettings.json中指定的连接字符串初始化数据库ORM。因此,此初始化代码依赖于IConfiguration可能在注册过程中注册到DI容器中的其他自定义服务Startup.ConfigureServices()

因此,根据这些文章的建议:

我试图将初始化逻辑封装在单独的类中,然后为该类创建扩展方法来IWebHostBuilder执行此代码,但是如何使框架注入IConfiguration和其他自定义依赖项进入此扩展方法?另外,我可以确定Startup.ConfigureServices()在注册所有依赖项之后,将执行此代码吗?

有没有更好的或推荐的方式来执行此类任务?

Kir*_*kin 6

您可以为IWebHost(而不是IWebHostBuilder)添加扩展方法,然后将其IWebHost.Services用于解析服务。这是有关如何检索的示例IConfiguration

public static class WebHostExtensions
{
    public static IWebHost SomeExtension(this IWebHost webHost)
    {
        var config = webHost.Services.GetService<IConfiguration>();

        // Your initialisation code here.
        // ...

        return webHost;
    }
}
Run Code Online (Sandbox Code Playgroud)

此扩展方法的用法如下所示:

CreateWebHostBuilder(args)
    .Build()
    .SomeExtension()
    .Run();
Run Code Online (Sandbox Code Playgroud)

如果您需要的async版本SomeExtension,则可以拆分上面的链接和await扩展方法。可能是这样的:

public static async Task SomeExtensionAsync(this IWebHost webHost)
{
    var config = webHost.Services.GetService<IConfiguration>();

    // Your initialisation code here with awaits.
    // ...
}
Run Code Online (Sandbox Code Playgroud)

用法看起来像这样:

public static async Task Main(string[] args)
{
    var webHost = CreateWebHostBuilder(args)
        .Build();

    await webHost.SomeExtensionAsync();

    webHost.Run();
}
Run Code Online (Sandbox Code Playgroud)

另外,我可以确定Startup.ConfigureServices()在注册所有依赖项之后,将执行此代码吗?

使用我上面概述的方法,这里的答案是肯定的。


请注意,它IWebHost.Services代表root IServiceProvider,它将不支持解析作用域的实例。IConfiguration是单例,因此这不是问题,但是如果您具有范围内的依赖项,则需要在扩展方法内部创建一个显式范围。


Chr*_*att 5

Program.cs的方法有以下代码Main

public static void Main(string[] args)
{
    CreateWebHostBuilder(args).Build().Run();
}
Run Code Online (Sandbox Code Playgroud)

Build()部分运行后,您就有了一个完全配置的主机。因此,您可以简单地执行如下操作:

var host = CreateWebHostBuilder(args).Build();

// do something with host

host.Run();
Run Code Online (Sandbox Code Playgroud)

主机有一个成员 ,Services它是 的实例IServiceProvider,因此您可以从中提取所需的任何服务,即

var config = host.Services.GetRequiredService<IConfiguration>();
Run Code Online (Sandbox Code Playgroud)

请记住,此时没有固有范围,因此如果您需要范围服务,则需要创建一个:

using (var scope = host.Services.CreateScope())
{
    var myScopedService = scope.ServiceProvider.GetRequiredService<MyScopedService>();
    // do something with myScopedService
}
Run Code Online (Sandbox Code Playgroud)