本文介绍了我应该在ASP.NET Core中的哪里执行自定义应用程序初始化步骤?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

ASP.NET Core framework gives us two well defined places for initialization:1. the Startup.ConfigureServices() method for registering DI services 2. the Startup.Configure() method for configuration of middleware pipeline

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

But what about other initialization steps specific to my web application? Where should those go, especially if they have dependencies that need to be injected?

例如,我需要基于在配置文件appsettings.json中指定的连接字符串来初始化数据库ORM.因此,此初始化代码依赖于 IConfiguration 以及在 Startup.ConfigureServices()

For example I need to initialize database ORM based on connection string which is specified in configuration file appsettings.json. So this initialization code has dependency on IConfiguration and perhaps other custom services that are registered into DI container during Startup.ConfigureServices()

根据这些文章的建议:

https://odetocode.com/blogs/scott/archive/2019/03/07/net-core-opinion-10-move-more-code-out-of.aspx

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

I tried to encapsulate initialization logic in separate classes and then to create extension method for IWebHostBuilder that would execute this code, but how can I make framework inject IConfiguration and other custom dependencies into this extension methods? Also, can I be sure that this code will be executed after Startup.ConfigureServices() when all dependencies are registered?

是否存在一些更好或推荐的方式来执行此类任务?

Is there some better or recommended way to perform this kind of tasks?

推荐答案

您可以为 IWebHost (而不是 IWebHostBuilder )添加扩展方法,然后使用 IWebHost.Services 用于解决服务.这是有关如何检索 IConfiguration

You can add an extension method for IWebHost (instead of IWebHostBuilder) and then use IWebHost.Services for resolving services. Here's an example of how to retrieve IConfiguration:

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

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

        return webHost;
    }
}

此扩展方法的用法如下:

Usage of this extension method would look something like this:

CreateWebHostBuilder(args)
    .Build()
    .SomeExtension()
    .Run();

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

If you need an async version of SomeExtension, you can split up the chaining above and await the extension method. Here's what that might look like:

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

    // Your initialisation code here with awaits.
    // ...
}

用法看起来像这样:

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

    await webHost.SomeExtensionAsync();

    webHost.Run();
}

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

With the approach I've outlined above, the answer here is yes.

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

Note that IWebHost.Services represents the root IServiceProvider, which will not support resolving scoped instances. IConfiguration is a singleton, so this isn't an issue for that, but if you have scoped dependencies, you'll need to create an explicit scope inside of your extension method.

这篇关于我应该在ASP.NET Core中的哪里执行自定义应用程序初始化步骤?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 12:46