然后我们将自界说的HostStartupLib这个Standard类库引入Web项目中,运行Web措施,发明HostingStartupInLib的Configure要领并不能被挪用。其实我们上面说过了,将HostingStartup从外部措施集引入的话需要手动指定启动措施集的名称。指定启动措施集的方法有两种,一种是指定IWebHostBuilder的扩展UseSetting指定
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { //通过UseSetting的方法指定措施集的名称 webBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "HostStartupLib"); //假如HostingStartup存在多个措施会合可以利用;脱离,好比HostStartupLib;HostStartupLib2 //webBuilder.UseSetting(WebHostDefaults.HostingStartupAssembliesKey, "HostStartupLib;HostStartupLib2"); webBuilder.UseStartup<Startup>(); });
另一种通过添加情况变量ASPNETCORE_HOSTINGSTARTUPASSEMBLIES的方法,可以通过配置launchSettings.json中
"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的观念及根基的利用方法,基于这些我们发生了几个疑问
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); }