千家信息网

如何在ASP.NET Core程序启动前运行代码

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,这篇文章主要讲解了"如何在ASP.NET Core程序启动前运行代码",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何在ASP.NET Core程序启
千家信息网最后更新 2025年01月31日如何在ASP.NET Core程序启动前运行代码

这篇文章主要讲解了"如何在ASP.NET Core程序启动前运行代码",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"如何在ASP.NET Core程序启动前运行代码"吧!

Step by Step

先说结论

因为这一篇文章更多的是在说明我在解决这个问题时的一步步思考,并没有涉及到代码的编写,所以下面的内容可能对你的帮助并不是很大,所以这里提前将实现的方式告诉大家。对于这个问题来说,只需要将我们想要执行的代码放到下面代码中注释所在的位置,即可实现我们的需求。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();

// do what you want

host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup();
});
}
前车之鉴

在尝试如何在 ASP.NET Core 中实现这一功能需求前,我们可以看看在 .NET Framework 中如何实现这一功能,是不是可以对我们在后续的功能实现中提供某些借鉴。

对于采用 .NET Framework 的应用程序来说,项目创建后会生成一个 Global.asax 文件,在这个类文件中存在着 Application_Start 这样的一个方法,而 Application_Start 这个方法实际上是在当应用程序接收到第一个 HTTP 请求时触发,也就是说,当系统运行后第一次接收到用户的请求,就会触发 Application_Start 中的代码逻辑,后续不管再接收到多少的请求,都不会再触发该方法。

例如在这个基于 .NET Framework 构建的 MVC 项目模板中,在程序运行前需要执行注册路由信息、注册过滤器、注册使用 bundle 压缩后的 js、css 文件等等。

但是在 ASP.NET Core 项目中,并没有原生存在这样的方法,那么我们如何在 ASP.NET Core 应用中自己动手实现类似的功能呢?

后事之师

了解了在之前版本中的实现方式,现在我们仔细看看 Application_Start 这个方法中执行的每行代码的功能,是不是特别像我们在 ASP.NET Core 项目中使用的各种中间件?

然而,如果你有使用过 ASP.NET Core 后就会知道,ASP.NET Core 中的中间件是会在每次请求时都会触发的,虽然我们可以在我们自定义的中间件中设置缓存中不存在数据就写入,存在就直接跳过的代码逻辑,但是既然除了第一次访问时才会真正执行该中间件的功能,后面完全用不到,因此,对于我这种略微强迫症的童鞋来说,这个真的不能忍。。。

既然中间件不可以,而我们需要的仅仅是只运行一次,提到 .NET Core,不知道你的第一印象是什么,对于我个人来说,无处不在的依赖注入,可能是我在 18 年开始学习 .NET Core 时的第一印象。我们知道,对于 .NET Core 中原生的依赖注入组件,存在着三种生命周期:Singleton、Scoped 以及 Transient,对于这三种生命周期的具体解释,还是推荐博客园里蒋金楠老师的一篇文章(电梯直达)。

对于采用 Singleton 方式注入的服务来说,因为是一种类似于全局单例的形式,不管后续从何处进行访问,都会访问的是同一个实例,那么,这里是不是就可以在此基础上实现我们的需求了呢?

很不幸,这里其实是有个很严重的逻辑上的问题的,依赖注入最终的目的是为了实现将我们定义的服务契约与实现进行解耦,实现服务的消费者只需要告诉依赖注入容器自己所需要服务的类型(服务接口 or 抽象服务类),就能自动得到与之匹配的服务实例。

简单点说就是,消费方要告诉服务提供方你要开始使用某个服务了,我才能给你提供对应的服务,就像我们去饭店吃饭,在点了菜后,没有必要关心厨师是用天然气 or 煤气给你烧的菜,但是能不能上菜的关键在于我们有没有点菜。因此,这个问题最终还是落在了我们应该在程序中的什么地方去调用我们设定好的方法。

绕了一圈,似乎我们的想法越来越偏,离我们想要实现的越来越远,既然路偏了,那就直接回到起点吧,抛弃我们在 .NET Framework 项目中的经验,重新从 ASP.NET Core 项目的启动流程开始看起。

在 ASP.NET Core 应用的启动过程中存在着两个非常重要的对象,对应到我们采用的 ASP.NET Core 3.X 的项目中则是 Host 以及 HostBuilder。这里的 Host 就是承载我们 Web 应用运行的载体,而 HostBuilder 则是用来构建 Host 对象的。

PS:因为 ASP.NET Core 3.0 开始加入了 对于 gRPC 框架和 Windows Service 的支持,同时为了与其它非 Web 服务器方案进行集成,因此将原来的 WebHost 和 WebHostBuilder 替换成了新的通用主机(generic-host)配置的模式 。当然,在 3.X 版本你还是可以使用 WebHost 和 WebHostBuilder 的,不过当然是不推荐的。

因为对于 ASP.NET Core 应用程序来说,本质上其实只是一个控制台应用,所以现在我们来看看对于一个控制台应用中最重要的文件:Program.cs, Program 类中的代码如下所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

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

代码很少,功能也很简单,简单来说,在 Main 方法中构建 HostBuilder 对象,然后去运行它,达到启动我们 Web 应用宿主的目的。

当然,在构建 HostBuilder 对象的过程中,会配置 Kestrel 服务器,会设置 ContentRoot,会加载配置文件等等一系列的动作,因为自己水平太次,尝试了一下,还是解释不好,如果你想要深入了解的话,建议配合博客园里面的这两篇文章一起食用(200行代码,7个对象--让你了解 ASP.NET Core 框架的本质、ASP.NET Core 2.0 : 七.一张图看透启动背后的秘密)。虽然参考文章中都是基于 ASP.NET Core 2.X 版本进行解释说明的,但其实最终的差异不是很大。

不知你是否找到了这个类中对于我们最重要的一点,在 Main 方法中,我们是先构建、再去运行,因此,我们是不是可以在构建完成后,先等一等,把我们想要实现的功能先调用了,再去运行我们的程序。嗯,让我们改造下 Main 方法中的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Program
{
public static void Main(string[] args)
{
var host = CreateHostBuilder(args).Build();

// Get logger
//
var logger = host.Services.GetRequiredService>();
logger.LogInformation("haha, I ran before web host starting");

host.Run();
}

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

感谢各位的阅读,以上就是"如何在ASP.NET Core程序启动前运行代码"的内容了,经过本文的学习后,相信大家对如何在ASP.NET Core程序启动前运行代码这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

代码 服务 运行 程序 方法 应用 功能 项目 中间件 对象 文件 问题 篇文章 还是 学习 重要 内容 就是 应用程序 方式 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 武汉软件开发专业技能树 信息网络安全监察这个专业如何 数据库目前存放数据库位置 网络安全外部威胁态势分析 计算机网络技术的兴趣爱好 u8 账套 数据库 网络安全技术选择题答案 电脑网络安全检测软件 网络安全基本属性不包括 化学需要学的网络技术 软件开发 技术文件 网络安全管理领导小组 金华天道网络技术有限公司 软件开发实际上是什么工作 网络安全法侵害个人信息罚款 服务器什么时候能安装 2021大学生网络安全ppt 在服务器里搭建网站教程 msc.marc材料数据库 服务器的时间为啥会少八分钟 网络安全跟编程 小学生国旗下网络安全演讲稿 临沂海创网络技术 深圳南山软件开发工程招聘 数据库技术三级2019 软件开发避免改出别的问题 浙江省农信联社软件开发面试 安卓如何清项目数据库 农业网络安全法律法规 vb修改数据库字段描述
0