简体   繁体   English

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

[英]Application startup code in ASP.NET Core

Reading over the documentation for ASP.NET Core , there are two methods singled out for Startup: Configure and ConfigureServices.通读ASP.NET Core文档,有两种用于启动的方法:Configure 和 ConfigureServices。

Neither of these seemed like a good place to put custom code that I would like to run at startup.这些似乎都不是放置我想在启动时运行的自定义代码的好地方。 Perhaps I want to add a custom field to my DB if it doesn't exist, check for a specific file, seed some data into my database, etc. Code that I want to run once, just at app start.也许我想在我的数据库中添加一个自定义字段,如果它不存在,检查特定文件,将一些数据种子到我的数据库等。我想运行一次的代码,就在应用程序启动时。

Is there a preferred/recommended approach for going about doing this?是否有首选/推荐的方法来执行此操作?

I agree with the OP.我同意 OP。

My scenario is that I want to register a microservice with a service registry but have no way of knowing what the endpoint is until the microservice is running.我的场景是我想向服务注册表注册一个微服务,但在微服务运行之前无法知道端点是什么。

I feel that both the Configure and ConfigureServices methods are not ideal because neither were designed to carry out this kind of processing.我觉得 Configure 和 ConfigureServices 方法都不理想,因为它们都不是为了执行这种处理而设计的。

Another scenario would be wanting to warm up the caches, which again is something we might want to do.另一种情况是想要预热缓存,这也是我们可能想要做的事情。

There are several alternatives to the accepted answer:接受的答案有几种选择:

  • Create another application which carries out the updates outside of your website, such as a deployment tool, which applies the database updates programmatically before starting the website创建另一个在您的网站之外执行更新的应用程序,例如部署工具,它在启动网站之前以编程方式应用数据库更新

  • In your Startup class, use a static constructor to ensure the website is ready to be started在您的 Startup 类中,使用静态构造函数来确保网站已准备好启动

Update更新

The best thing to do in my opinion is to use the IApplicationLifetime interface like so:在我看来,最好的做法是像这样使用 IApplicationLifetime 接口:

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

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

Basically there are two entry points for such custom code at startup time.基本上,此类自定义代码在启动时有两个入口点。

1.) Main method 1.) Main方法

As a ASP.NET Core application has got the good old Main method as entry point you could place code before the ASP.NET Core startup stuff, like由于 ASP.NET Core 应用程序已经使用了旧的Main方法作为入口点,因此您可以在 ASP.NET Core 启动内容之前放置代码,例如

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.) Use your Startup class 2.) 使用你的Startup

As you already stated in your question is the Configure and ConfigureServices a good place for your custom code.正如您在问题中已经说过的, ConfigureConfigureServices是您自定义代码的好地方。

I would prefer the Startup class.我更喜欢Startup课程。 From the runtime perspective it does not matter, if the call is called in startup or somewhere else before the host.Run() call.从运行时的角度来看,调用是在启动时还是在host.Run()调用之前的其他地方调用并不重要。 But from a programmer's point of view who is accustomed to the ASP.NET framework then his first look for such logic would be the Startup.cs file.但是,从习惯于 ASP.NET 框架的程序员的角度来看,他首先要寻找这样的逻辑将是Startup.cs文件。 All samples and templates put there the logic for Identity, Entity Framework initialization and so on.所有示例和模板都将用于标识、实体框架初始化等的逻辑放在那里。 So as a convention I recommend to place the initialization stuff there.所以作为惯例,我建议将初始化的东西放在那里。

This can be done by creating an IHostedService implementation and registering it using IServiceCollection.AddHostedService<>() in ConfigureServices() in your startup class.这可以通过创建IHostedService实现并在启动类的ConfigureServices()中使用IServiceCollection.AddHostedService<>()注册它来完成。

Example示例

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>();
    }
}

Notes笔记

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM