这篇文章主要介绍了深入探究ASP.NET Core Startup初始化问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
前言
Startup类相信大家都比较熟悉,在我们使用ASP.NET Core开发过程中经常用到的类,我们通常使用它进行IOC服务注册,配置中间件信息等。虽然它不是必须的,但是将这些操作统一在Startup中做处理,会在实际开发中带来许多方便。当我们谈起Startup类的时候你有没有好奇过以下几点
为何我们自定义的Startup可以正常工作。
我们定义的Startup类中ConfigureServices和Configure只能叫这个名字才能被调用到吗?
在使用泛型主机(IHostBuilder)时Startup的构造函数,为何只支持注入IWebHostEnvironment、IHostEnvironment、IConfiguration。
ConfigureServices方法为何只能传递IServiceCollection实例。
Configure方法的参数为何可以是所有在IServiceCollection注册服务实例。
在ASP.NET Core结合Autofac使用的时候为何我们添加的ConfigureContainer方法会被调用。
带着以上几点疑问,我们将在本篇文章中探索Startup的源码,来了解Startup初始化过程到底为我们做了些什么。
Startup的另类指定方式
在日常编码过程中,我们通常使用UseStartup的方式来引入Startup类。但是这并不是唯一的方式,还有一种方式是在配置节点中指定Startup所在的程序集来自动查找Startup类,这个我们可以在GenericWebHostBuilder的构造函数源码中的找到相关代码[点击查看源码]相信熟悉ASP.Net Core启动流程的同学对GenericWebHostBuilder这个类都比较了解。ConfigureWebHostDefaults方法中其实调用了ConfigureWebHost方法,ConfigureWebHost方法中实例化了GenericWebHostBuilder对象,启动流程不是咱们的重点,所以这里只是简单描述一下。直接找到我们需要的代码如下所示
//判断是否配置了StartupAssembly参数
if (!string.IsNullOrEmpty(webHostOptions.StartupAssembly))
{
try
{
//根据你配置的程序集去查找Startup
var startupType = StartupLoader.FindStartupType(webHostOptions.StartupAssembly, webhostContext.HostingEnvironment.EnvironmentName);
UseStartup(startupType, context, services);
}
catch (Exception ex) when (webHostOptions.CaptureStartupErrors)
{
//此处省略代码省略
}
}
这里我们可以看出来,我们需要配置StartupAssembly对应的程序集,它可以通过StartupLoader的FindStartupType方法加载程序集中对应的类。我们还可以看到它还传递了EnvironmentName环境变量,至于它起到了什么作用,我们继续往下看。
首先我们需要找到webHostOptions.StartupAssembly是如何被初始化的,在WebHostOptions的构造函数中我们找到了StartupAssembly初始化的地方[点击查看源码]