ASP.NET 核心中的应用程序启动代码

Application startup code in ASP.NET Core

仔细阅读 documentation for ASP.NET Core,有两种启动方法:Configure 和 ConfigureServices。

这些似乎都不是放置我想要在启动时 运行 的自定义代码的好地方。也许我想在我的数据库中添加一个自定义字段(如果它不存在)、检查特定文件、将一些数据植入我的数据库等。我想 运行 一次的代码,就在应用程序启动时。

是否有 preferred/recommended 方法来执行此操作?

在启动时,此类自定义代码基本上有两个入口点。

1.) Main 方法

作为一个 ASP.NET 核心应用程序有很好的旧 Main 方法作为入口点,你可以将代码放在 ASP.NET 核心启动的东西之前,比如

public class Program
{
    public static void Main(string[] args)
    {
        // call custom startup logic here
        AppInitializer.Startup();

        var host = new WebHostBuilder()
            .UseKestrel()
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }
}

2.) 使用你的 Startup class

正如您在问题中所述,ConfigureConfigureServices 是放置自定义代码的好地方。

我更喜欢 Startup class。从运行时的角度来看,调用是在启动时调用还是在 host.Run() 调用之前的其他地方调用并不重要。但是从一个习惯于 ASP.NET 框架的程序员的角度来看,他首先寻找这样的逻辑将是 Startup.cs 文件。所有示例和模板都将身份、Entity Framework 初始化等逻辑放在其中。因此,作为惯例,我建议将初始化内容放在那里。

我同意 OP。

我的场景是我想在服务注册表中注册一个微服务,但在微服务 运行.

之前无法知道端点是什么

我觉得 Configure 和 ConfigureServices 方法都不理想,因为它们都不是为执行这种处理而设计的。

另一种情况是想要预热缓存,这也是我们可能想要做的事情。

已接受的答案有多种选择:

  • 创建另一个在您的网站之外执行更新的应用程序,例如部署工具,它在启动网站之前以编程方式应用数据库更新

  • 在您的 Startup class 中,使用静态构造函数确保网站已准备好启动

更新

我认为最好的做法是像这样使用 IApplicationLifetime 接口:

public class Startup
{
    public void Configure(IApplicationLifetime lifetime)
    {
        lifetime.ApplicationStarted.Register(OnApplicationStarted);
    }

    public void OnApplicationStarted()
    {
        // Carry out your initialisation.
    }
}

这可以通过创建一个 IHostedService 实现并使用 IServiceCollection.AddHostedService<>()ConfigureServices() 中注册它来完成 class。

例子

using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;

public class MyInitializer : IHostedService
{
    public Task StartAsync(CancellationToken cancellationToken)
    {
        // Do your startup work here

        return Task.CompletedTask;
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        // We have to implement this method too, because it is in the interface

        return Task.CompletedTask;
    }
}
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHostedService<MyInitializer>();
    }
}

备注