深入探究ASP.NET Core Startup初始化问题
副问题[/!--empirenews.page--]
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情形变量,至于它起到了什么浸染,我们继承往下看。 StartupAssembly = configuration[WebHostDefaults.StartupAssemblyKey]; 从这里也可以看出来它的值来于设置,它的key来自WebHostDefaults.StartupAssemblyKey这个常量值,最后我们找到了的值为 public static readonly string StartupAssemblyKey = "startupAssembly"; 也就是说只要我们给startupAssembly设置Startup地址的措施集名称,它就可以在措施齐集查找Startup类举办初始化,如下所示 public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureHostConfiguration(config=> { List<KeyValuePair<string, string>> keyValuePairs = new List<KeyValuePair<string, string>>(); //设置Startup地址的措施集名称 keyValuePairs.Add(new KeyValuePair<string, string>("startupAssembly", "Startup地址的措施集名称")); config.AddInMemoryCollection(keyValuePairs); }) .ConfigureWebHostDefaults(webBuilder => { //这样的话这里就可以省略了 //webBuilder.UseStartup<Startup>(); }); 回到上面的思绪,我们在StartupLoader类中查察FindStartupType要领,来看下它是通过什么法则来查找Startup的[点击查察源码👈]精简之后的代码大抵如下 public static Type FindStartupType(string startupAssemblyName, string environmentName) { var assembly = Assembly.Load(new AssemblyName(startupAssemblyName)); //名称Startup+情形变量的类好比(StartupDevelopment) var startupNameWithEnv = "Startup" + environmentName; //名称为Startup的类 var startupNameWithoutEnv = "Startup"; // 先查找包括名称Startup+情形变量的相干类,假如找不到则查找名称为Startup的类 var type = assembly.GetType(startupNameWithEnv) ?? assembly.GetType(startupAssemblyName + "." + startupNameWithEnv) ?? assembly.GetType(startupNameWithoutEnv) ?? assembly.GetType(startupAssemblyName + "." + startupNameWithoutEnv); if (type == null) { // 假如上述法则找不到,则在措施集界说的全部类中继承查找 var definedTypes = assembly.DefinedTypes.ToList(); var startupType1 = definedTypes.Where(info => info.Name.Equals(startupNameWithEnv, StringComparison.OrdinalIgnoreCase)); var startupType2 = definedTypes.Where(info => info.Name.Equals(startupNameWithoutEnv, StringComparison.OrdinalIgnoreCase)); var typeInfo = startupType1.Concat(startupType2).FirstOrDefault(); if (typeInfo != null) { type = typeInfo.AsType(); } } //最终返回Startup范例 return type; } 通过上述代码我们可以看到在通过设置指定措施集时是怎样查找指定法则的Startup类的,根基上可以领略为先去查找名称为Startup+情形变量的类,假如找不到则继承查找名称为Startup的类,最终会返回Startup的范例转达给UseStartup要领。着实我们最常行使的UseStartup()要领最终也是转换成UseStartup(typeof(T))的方法,以是最终这两种方法走到了沟通的处所,接下来我们步入正题,来一路探讨一下Starup毕竟是怎样被初始化的。 Startup的结构函数 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |