ASP.NET Core Controller与IOC团结问题整理(2)

用过上面的源码可知,真正建设Controller的处地址_controllerActivator.Create要领中,通过上面的源码可知为IControllerActivator默认注册的是DefaultControllerActivator类,直接找到源码位置[点击查察源码],我们继承简化一下源码如下所示

internal class DefaultControllerActivator : IControllerActivator { private readonly ITypeActivatorCache _typeActivatorCache; public DefaultControllerActivator(ITypeActivatorCache typeActivatorCache) { _typeActivatorCache = typeActivatorCache; } /// <summary> /// Controller实例的建设要领 /// </summary> public object Create(ControllerContext controllerContext) { //获取Controller范例信息 var controllerTypeInfo = controllerContext.ActionDescriptor.ControllerTypeInfo; //获取ServiceProvider var serviceProvider = controllerContext.HttpContext.RequestServices; //建设controller实例 return _typeActivatorCache.CreateInstance<object>(serviceProvider, controllerTypeInfo.AsType()); } /// <summary> /// 释放Controller实例 /// </summary> public void Release(ControllerContext context, object controller) { //假如controller实现了IDisposable接口,那么Release的时候会自动挪用Controller的Dispose要领 //假如我们在Controller中存在需要释放可能封锁的操纵,可以再Controller的Dispose要领中统一释放 if (controller is IDisposable disposable) { disposable.Dispose(); } } }

通过上面的代码我们依然要继承深入到ITypeActivatorCache实现中去寻找谜底,通过查察MvcCoreServiceCollectionExtensions类的AddMvcCoreServices要领源码我们可以找到如下信息

services.TryAddSingleton<ITypeActivatorCache, TypeActivatorCache>();

有了这个信息,我们可以直接找到TypeActivatorCache类的源码[点击查察源码]代码并不多,大抵如下所示

internal class TypeActivatorCache : ITypeActivatorCache { //建设ObjectFactory的委托 private readonly Func<Type, ObjectFactory> _createFactory = (type) => ActivatorUtilities.CreateFactory(type, Type.EmptyTypes); //Controller范例和对应建设Controller实例的ObjectFactory实例的缓存 private readonly ConcurrentDictionary<Type, ObjectFactory> _typeActivatorCache = new ConcurrentDictionary<Type, ObjectFactory>(); /// <summary> /// 真正建设实例的处所 /// </summary> public TInstance CreateInstance<TInstance>( IServiceProvider serviceProvider, Type implementationType) { //真正建设的操纵是createFactory //通过Controller范例在ConcurrentDictionary缓存中得到ObjectFactory //而ObjectFactory实例由ActivatorUtilities.CreateFactory要领建设的 var createFactory = _typeActivatorCache.GetOrAdd(implementationType, _createFactory); //返回建设实例 return (TInstance)createFactory(serviceProvider, arguments: null); } }

通过上面类的代码我们可以清晰的得出一个结论,默认环境下Controller实例是由ObjectFactory建设出来的,而ObjectFactory实例是由ActivatorUtilities的CreateFactory建设出来,所以Controller实例每次都是由ObjectFactory建设而来,并非注册到IOC容器中。而且我们还可以获得一个结论ObjectFactory应该是一个委托,我们找到ObjectFactory界说的处所[点击查察源码]

delegate object ObjectFactory(IServiceProvider serviceProvider, object[] arguments);

这个确实如我们意料的那般,这个委托会通过IServiceProvider实例去构建范例的实例,通过上述源码相关的描写我们会发生一个疑问,既然Controller实例并非由IOC容器托管,它由ObjectFactory建设而来,可是ObjectFactory实例又是由ActivatorUtilities构建的,那么出产工具的焦点也就在ActivatorUtilities类中,接下来我们就来探究一下ActivatorUtilities的神秘面纱。

ActivatorUtilities类的探究

书接上面,我们知道了ActivatorUtilities类是建设Controller实例最底层的处所,那么ActivatorUtilities到底和容器是啥干系,因为我们看到了ActivatorUtilities建设实例需要依赖ServiceProvider,一切都要从找到ActivatorUtilities类的源码开始。我们最初打仗这个类的处地址于它通过CreateFactory要领建设了ObjectFactory实例,那么我们就从这个处所开始,找到源码位置[]实现如下

public static ObjectFactory CreateFactory(Type instanceType, Type[] argumentTypes) { //查找instanceType的结构函数 //找到结构信息ConstructorInfo //获得给定范例与查找范例instanceType结构函数的映射干系 FindApplicableConstructor(instanceType, argumentTypes, out ConstructorInfo constructor, out int?[] parameterMap); //构建IServiceProvider范例参数 var provider = Expression.Parameter(typeof(IServiceProvider), "provider"); //构建给定范例参数数组参数 var argumentArray = Expression.Parameter(typeof(object[]), "argumentArray"); //通过结构信息、结构参数对应干系、容器和给定范例构建表达式树Body var factoryExpressionBody = BuildFactoryExpression(constructor, parameterMap, provider, argumentArray); //构建lambda var factoryLamda = Expression.Lambda<Func<IServiceProvider, object[], object>>( factoryExpressionBody, provider, argumentArray); var result = factoryLamda.Compile(); //返回执行功效 return result.Invoke; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsdxys.html