运行 ASP.Net 核心应用程序启动期间的异步代码

Run async code during startup in a ASP.Net Core application

将函数 ConfigureServices 的签名更改为异步后(最初它只是一个无效的同步函数,应用程序运行良好),我收到以下错误:

Unable to find the required services. Please add all the required services by calling IServiceCollection.AddAuthorization inside the call to ConfigureServices(...) in the application startup code.

下面是我的 ConfigureServices 函数的代码。

// This method gets called by the runtime. Use this method to add services to the container.
public async Task ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();

    // Create the necessary Cosmos DB infrastructure
    await CreateDatabaseAsync();
    await CreateContainerAsync();
}

ConfigureServices 在运行时自动调用。

签名不能随便改,需要为void才能被框架调用

现在当你把它改成Task的时候,就意味着框架找不到它,所以它根本不会被调用。

这里有一个 GitHub 问题:https://github.com/dotnet/aspnetcore/issues/5897

虽然这很棘手...

There's no progress for 5.0 no, we don't know how to do this without blocking or breaking changes. It might be possible to run filters in 2 stages that never overlap.

根据您的评论更新: 如果你想在启动时 运行 一些异步的东西,我通常这样做:

我创建了一个这样的界面:

public interface IStartupTask
{
     Task Execute();
}

然后像这样的示例实现

public class CreateDatabaseStartupTask : IStartupTask
{
    public async Task Execute()
    {
          // My logic here
          // await CreateDatabaseAsync();
    }
}

然后在我的Program.cs

public static async Task Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();
    
    // Resolve the StartupTasks from the ServiceProvider
    var startupTasks = host.Services.GetServices<IStartupTask>();
    
    // Run the StartupTasks
    foreach(var startupTask in startupTasks)
    {
        await startupTask.Execute();
    }
    await host.RunAsync();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
}

还有我的创业公司

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddTransient<IStartupTask, CreateDatabaseStartupTask>();
    }
}

所以重要的事情是:

  1. 注册您的 StartupTasks
  2. 构建主机
  3. 解决 StartupTasks
  4. 运行 启动任务
  5. 启动主机