应用程序启动代码.净的核心
本文关键字:核心 代码 启动 应用程序 | 更新日期: 2023-09-27 18:03:07
阅读ASP的文档。. NET Core中,有两个方法专门用于Startup: Configure和ConfigureServices。
这两个地方都不像是放置我想在启动时运行的自定义代码的好地方。也许我想添加一个自定义字段到我的数据库,如果它不存在,检查一个特定的文件,种子一些数据到我的数据库等。我想运行一次的代码,就在应用程序启动时。
是否有首选/推荐的方法来做这件事?
我同意op。
我的场景是,我想用服务注册中心注册一个微服务,但在微服务运行之前没有办法知道端点是什么。
我觉得Configure和ConfigureServices方法都不理想,因为它们都不是为执行这种处理而设计的。
另一种情况是想要预热缓存,这也是我们可能想要做的事情。
对于可接受的答案,有几个替代方案:
-
创建另一个应用程序,在您的网站之外进行更新,例如部署工具,在启动网站之前以编程方式应用数据库更新
-
在你的Startup类中,使用一个静态构造函数来确保网站已经准备好启动
在我看来,最好的办法是像这样使用IApplicationLifetime接口:
public class Startup
{
public void Configure(IApplicationLifetime lifetime)
{
lifetime.ApplicationStarted.Register(OnApplicationStarted);
}
public void OnApplicationStarted()
{
// Carry out your initialisation.
}
}
这可以通过创建IHostedService
实现并在启动类的ConfigureServices()
中使用IServiceCollection.AddHostedService<>()
来注册它来完成。
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>();
}
}
指出- 主应用程序将不会启动,直到你的代码完成执行。
- 构造函数依赖注入可用于
IHostedService
实现。 - 我可以推荐这篇博客文章获得更多信息,以及如何使用async的一个例子:https://andrewlock.net/running-async-tasks-on-app-startup-in-asp-net-core-3/
- 有关更多背景阅读,请参阅此讨论:https://github.com/dotnet/aspnetcore/issues/10137
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>();
}
}
IHostedService
实现。基本上在启动时有两个自定义代码入口点。
1。)
作为ASP。. NET Core应用程序有一个很好的老Main
方法作为入口点,你可以把代码放在ASP. js之前。. 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。)使用Startup
类
正如你已经在你的问题中所说的,Configure
和ConfigureServices
是你自定义代码的好地方。
我更喜欢Startup
类。从运行时的角度来看,如果在启动时或在host.Run()
调用之前的其他地方调用该调用,则无关紧要。但是从一个习惯了ASP的程序员的角度来看。. NET框架,那么他的第一个寻找这样的逻辑将是Startup.cs
文件。所有的样本和模板都包含了身份、实体框架初始化等逻辑。按照惯例,我建议把初始化的东西放在这里