加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_阳江站长网 (https://www.0662zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 创业 > 政策 > 正文

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

发布时间:2020-12-11 22:21:37 所属栏目:政策 来源:做站长
导读:这篇文章主要介绍了深入探究ASP.NET Core Startup初始化问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 前言 Startup类相信大家都比较熟悉,在我们使用ASP.NET Core开发过程中经常用到的类,我们通常使用

}
//如果不存在包含环境变量的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;
}

通过FindMethod方法我们可以得到几个结论,首先ConfigureServices方法的名称可以是包含环境变量的名称比如(ConfigureDevelopmentServices),其次方法可以为共有的静态或非静态方法。FindMethod方法是真正执行查找的逻辑所在,如果找到相关方法则返回MethodInfo。FindMethod查找的方法名称是通过methodName参数传递进来的,我们标注的注释代码都是直接写死了ConfigureServices方法,只是为了便于说明理解,但其实FindMethod是通用方法,接下来我们要讲解的内容还会涉及到这个方法,到时候关于这个代码的逻辑我们就不会在进行说明了,因为是同一个方法,希望大家能注意到这一点。

通过上面的相关方法,我们了解到了是通过什么样的规则去查找到ConfigureServices的方法信息的,我们也看到了ConfigureServicesBuilder正是通过查找到的MethodInfo去构造实例的,接下来我们就来查看下ConfigureServicesBuilder的实现源码[点击查看源码]

internal class ConfigureServicesBuilder
{
//构造函数传递的configureServices的MethodInfo
public ConfigureServicesBuilder(MethodInfo configureServices)
{
MethodInfo = configureServices;
}

public MethodInfo MethodInfo { get; }
public Func<Func<IServiceCollection, IServiceProvider>, Func<IServiceCollection, IServiceProvider>> StartupServiceFilters { get; set; } = f => f;
//Build委托
public Func<IServiceCollection, IServiceProvider> Build(object instance) => services => Invoke(instance, services);
private IServiceProvider Invoke(object instance, IServiceCollection services)
{
//执行StartupServiceFilters委托参数为Func<IServiceCollection, IServiceProvider>类型的委托方法即Startup
//返回了Func<IServiceCollection, IServiceProvider>委托,执行这个委托需传递services即IServiceCollections实例返回IServiceProvider类型
return StartupServiceFilters(Startup)(services);
IServiceProvider Startup(IServiceCollection serviceCollection) => InvokeCore(instance, serviceCollection);
}

private IServiceProvider InvokeCore(object instance, IServiceCollection services)
{
if (MethodInfo == null)
{
return null;
}
// 如果ConfigureServices方法包含多个参数或方法参数类型不是IServiceCollection类型则直接抛出异常
// 也就是说ConfigureServices只能包含一个参数且类型为IServiceCollection
var parameters = MethodInfo.GetParameters();
if (parameters.Length > 1 ||
parameters.Any(p => p.ParameterType != typeof(IServiceCollection)))
{
throw new InvalidOperationException(“The ConfigureServices method must either be parameterless or take only one parameter of type IServiceCollection.”);
}
//找到ConfigureServices方法的参数,并将services即IServiceCollection的实例传递给这个参数
var arguments = new object[MethodInfo.GetParameters().Length];
if (parameters.Length > 0)
{
arguments[0] = services;
}
// 执行返回IServiceProvider实例
return MethodInfo.InvokeWithoutWrappingExceptions(instance, arguments) as IServiceProvider;
}
}

(编辑:应用网_阳江站长网)

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

热点阅读