加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

深入探究ASP.NET Core Startup初始化问题

发布时间:2020-12-10 20:54:59 所属栏目:编程 来源:网络整理
导读:这篇文章首要先容了深入探讨ASP.NET Core Startup初始化题目,本文给各人先容的很是具体,对各人的进修或事变具有必然的参考小心代价,必要的伴侣可以参考下

这里的startupType就是我们转达的Startup范例,关于ActivatorUtilities这个类照旧较量适用的,它为我们提供了很多辅佐我们实例化工具的要领,在一般编程中假若有必要可以行使这个类。上面的ActivatorUtilities的CreateInstance要领的成果就是按照转达IServiceProvider范例的工具去实例化指定的范例工具,我们这里的范例就是startupType。它的行使场景就是,假如某个范例必要用过有参结构函数去实例化,而结构函数的参数可以来自于IServiceProvider的实例,那么行使这个要领就在吻合不外了。上面的代码转达的IServiceProvider的实例是HostServiceProvider工具,接下来我们找到它的实现源码[点击查察源码👈]代码并不多我们就所有粘贴出来

private class HostServiceProvider : IServiceProvider { private readonly WebHostBuilderContext _context; public HostServiceProvider(WebHostBuilderContext context) { _context = context; } public object GetService(Type serviceType) { // 通过这里我们就较量清楚的看出,只有满意这几种环境下才气返回详细的实例,其他的城市返回null #pragma warning disable CS0618 // Type or member is obsolete if (serviceType == typeof(Microsoft.Extensions.Hosting.IHostingEnvironment) || serviceType == typeof(Microsoft.AspNetCore.Hosting.IHostingEnvironment) #pragma warning restore CS0618 // Type or member is obsolete || serviceType == typeof(IWebHostEnvironment) || serviceType == typeof(IHostEnvironment) ) { return _context.HostingEnvironment; } if (serviceType == typeof(IConfiguration)) { return _context.Configuration; } //不满意这几种环境的范例都返回null return null; } }

通过这个内部私有类我们就能清楚的看到为何Starup的结构函数只能注入IWebHostEnvironment、IHostEnvironment、IConfiguration相干实例了,HostServiceProvider类实现了IServiceProvider的GetService要领并做了判定,只有满意这几种范例才气返回详细的实例注入,其余不满意前提的范例城市返回null。因此在初始化Starup实例的时辰,通过结构函数注入的范例也就只能是这几种了。最终通过这个结构函数初始化了Startup类的实例。

ConfigureServices的装载

接下来我们就来在UseStartup要领里继承查察是怎样查找并执行ConfigureServices要领的,继承查察找到如下实现[点击查察源码👈]

//转达startupType和情形变量参数查找返回ConfigureServicesBuilder var configureServicesBuilder = StartupLoader.FindConfigureServicesDelegate(startupType, context.HostingEnvironment.EnvironmentName); //挪用Build要领返回ConfigureServices委托 var configureServices = configureServicesBuilder.Build(instance); //转达services工具即IServiceCollection工具挪用ConfigureServices要领 configureServices(services);

从上述代码中我们可以相识到查找并执行ConfigureServices要领的详细步调可分为三步,起首在startupType范例中按照情形变量名称查找详细要领返回ConfigureServicesBuilder实例,然后构建ConfigureServicesBuilder实例返回ConfigureServices要领的委托,最后转达IServiceCollection工具执行委托要领。接下来我们就来查察详细实现源码。
我们在StartupLoader类中找到了FindConfigureServicesDelegate要领的相干实现[点击查察源码👈]

internal static ConfigureServicesBuilder FindConfigureServicesDelegate(Type startupType, string environmentName) { //按照startupType和按照environmentName构建的Configure{0}Services字符串先去查找返回范例为IServiceProvider的要领 //找不到在查找返回值为void范例的要领 var servicesMethod = FindMethod(startupType, "Configure{0}Services", environmentName, typeof(IServiceProvider), required: false) ?? FindMethod(startupType, "Configure{0}Services", environmentName, typeof(void), required: false); //按照查找的到的MethodInfo去构建ConfigureServicesBuilder实例 return new ConfigureServicesBuilder(servicesMethod); }

通过这里的源码我们可以看到在startupType范例里去查找名字为environmentName构建的Configure{0}Services的要领信息,然后按照查找的要领信息即MethodInfo工具去构建ConfigureServicesBuilder实例。接下里我们就来查询FindMethod要领的实现

private static MethodInfo FindMethod(Type startupType, string methodName, string environmentName, Type returnType = null, bool required = true) { //包括情形变量的ConfigureServices要领名称好比(ConfigureDevelopmentServices) var methodNameWithEnv = string.Format(CultureInfo.InvariantCulture, methodName, environmentName); //名为ConfigureServices的要领 var methodNameWithNoEnv = string.Format(CultureInfo.InvariantCulture, methodName, ""); //要领是共有的静态的或非静态的要领 var methods = startupType.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); //查找包括情形变量的ConfigureServices要领名称 var selectedMethods = methods.Where(method => method.Name.Equals(methodNameWithEnv, StringComparison.OrdinalIgnoreCase)).ToList(); if (selectedMethods.Count > 1) { //找打多个满意法则的要领直接抛出非常 throw new InvalidOperationException(string.Format("Having multiple overloads of method '{0}' is not supported.", methodNameWithEnv)); } //假如不存在包括情形变量的ConfigureServices的要领好比(ConfigureDevelopmentServices),则直接查找要领名为ConfigureServices的要领 if (selectedMethods.Count == 0) { selectedMethods = methods.Where(method => method.Name.Equals(methodNameWithNoEnv, StringComparison.OrdinalIgnoreCase)).ToList(); //假如存在多个则同样抛出非常 if (selectedMethods.Count > 1) { throw new InvalidOperationException(string.Format("Having multiple overloads of method '{0}' is not supported.", methodNameWithNoEnv)); } } var methodInfo = selectedMethods.FirstOrDefault(); //假如没找到满意法则的要领,而且满意required参数,则抛出未找到要领的非常 if (methodInfo == null) { if (required) { throw new InvalidOperationException(string.Format("A public method named '{0}' or '{1}' could not be found in the '{2}' type.", methodNameWithEnv, methodNameWithNoEnv, startupType.FullName)); } return null; } //假如找到了名称同等的要领,可是返回范例和预期的纷歧致,也抛出非常 if (returnType != null && methodInfo.ReturnType != returnType) { if (required) { throw new InvalidOperationException(string.Format("The '{0}' method in the type '{1}' must have a return type of '{2}'.", methodInfo.Name, startupType.FullName, returnType.Name)); } return null; } return methodInfo; }

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读