设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 数据 手机
当前位置: 首页 > 站长学院 > Asp教程 > 正文

ASP.NET Core使用HostingStartup增强启动操作方法详解(3)

发布时间:2020-12-10 09:52 所属栏目:120 来源:网络整理
导读:"environmentVariables": { "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "HostStartupLib" //如果HostingStartup存在多个程序集中可以使用;分隔,比如HostStartupLib;HostStartupLib2 //"ASPNETCORE_HOSTINGSTARTUPASSE

"environmentVariables": { "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "HostStartupLib" //如果HostingStartup存在多个程序集中可以使用;分隔,比如HostStartupLib;HostStartupLib2 //"ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "HostStartupLib;HostStartupLib2" }

可以引入多个包含HostingStartup的程序集,在设置WebHostDefaults.HostingStartupAssembliesKey或者ASPNETCORE_HOSTINGSTARTUPASSEMBLIES指定多个程序集名称可以使用英文分号(;)隔开程序集名称。虽然是两种形似指定,但是其实本质是一样的那就是设置配置key为hostingStartupAssemblie配置的值,下面我们会详细讲解。
通过在程序中设置环境变量的方式等同于Window系统中Set的方式设置环境变量,或Linux系统中export的方式设置环境变量,亦或是直接设置系统环境变量,效果都是一致的。指定完成启动程序集之后,再次运行程序便可以看到HostingStartupInLib的Configure方法被调用到了。在这里我们可以看到如果是使用的环境变量的方式去指定启动程序集的话,对现有代码可以做到完全无入侵。

源码探究

在上面我们简单的介绍了HostingStartup的概念及基本的使用方式,基于这些我们产生了几个疑问

首先是关于HostingStartup的基本工作方式是什么

其次是为什么HostingStartup在Web程序中不需要配置程序集信息就可以被调用到,而通过外部程序集引入HostingStartup需要手动指定程序集

最后是通过外部程序集引入HostingStartup的指定方式为何只能是UseSetting和环境变量的方式

基于以上几个疑问,我们来探索一下HostingStartup的相关源码,来揭开它的神秘面纱。首先废话不多说直接找到源码位置[点击查看源码👈]在GenericWebHostBuilder类中的ExecuteHostingStartups方法中,关于GenericWebHostBuilder类我们在上篇文章深入探究ASP.NET Core Startup初始化中主要就是分析这个类,因为这是构建WebHost的默认类,而我们接下来要说的ExecuteHostingStartups方法也是承载在这个类中,直接贴代码如下所示

private void ExecuteHostingStartups() { //通过配置_config和当前程序集名称构建WebHostOptions类 var webHostOptions = new WebHostOptions(_config, Assembly.GetEntryAssembly()?.GetName().Name); //如果PreventHostingStartup属性为true则直接返回 //通过这个可以配置阻止启动逻辑 if (webHostOptions.PreventHostingStartup) { return; } var exceptions = new List<Exception>(); //构建HostingStartupWebHostBuilder _hostingStartupWebHostBuilder = new HostingStartupWebHostBuilder(this); //GetFinalHostingStartupAssemblies获取最终要执行的程序集名称 foreach (var assemblyName in webHostOptions.GetFinalHostingStartupAssemblies().Distinct(StringComparer.OrdinalIgnoreCase)) { try { //通过程序集名称加载程序集信息,因为使用了AssemblyName所以只需要使用程序集名称即可 var assembly = Assembly.Load(new AssemblyName(assemblyName)); //获取包含HostingStartupAttribute的程序集 foreach (var attribute in assembly.GetCustomAttributes<HostingStartupAttribute>()) { //实例化HostingStartupAttribute的HostingStartupType属性的对象实例 //即我们上面声明的[assembly: HostingStartup(typeof(HostStartupWeb.HostingStartupInWeb))] var hostingStartup = (IHostingStartup)Activator.CreateInstance(attribute.HostingStartupType); //调用HostingStartup的Configure方法 hostingStartup.Configure(_hostingStartupWebHostBuilder); } } catch (Exception ex) { exceptions.Add(new InvalidOperationException($"Startup assembly {assemblyName} failed to execute. See the inner exception for more details.", ex)); } } if (exceptions.Count > 0) { _hostingStartupErrors = new AggregateException(exceptions); } }

通过上面的源码我们就可以很清楚的了解到HostingStartup的基本工作方式。获取的程序集中包含的HostingStartupAttribute,通过获取HostingStartupAttribute的HostingStartupType属性得到要执行的IHostingStartup实例,最后执行Configure方法,Configure方法需要传递IWebHostBuilder的实例,而HostingStartupWebHostBuilder正是实现了IWebHostBuilder接口。
我们了解到了HostStartup的工作方式,接下来我们来探究一下为什么HostingStartup在Web程序中不需要配置程序集信息就可以被调用到,而通过外部程序集引入HostingStartup需要手动指定程序集。通过上面的源码我们可以得到一个信息那就是所有需要启动的程序集信息都是来自WebHostOptions的GetFinalHostingStartupAssemblies方法,接下来我们就来查看一下GetFinalHostingStartupAssemblies方法的实现源码[点击查看源码👈]

public IEnumerable<string> GetFinalHostingStartupAssemblies() { return HostingStartupAssemblies.Except(HostingStartupExcludeAssemblies, StringComparer.OrdinalIgnoreCase); }

从这里我们可以看出程序集信息来自于HostingStartupAssemblies属性,而且还要排除掉HostingStartupExcludeAssemblies包含的程序集。我们找到他们初始化的相关逻辑大致如下

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读