最后来看看前面一直说的Engine(工作引擎),工作引擎接口是IServiceProviderEngineServiceProvider的构造函数中看到了根据指定的Mode创建了不同的实现类,下面先来看一下IServiceProviderEngine接口和其实现类的整体结构

IServiceProviderEngine类型继承关系

internal interface IServiceProviderEngine : IDisposable, IServiceProvider
{
IServiceScope RootScope { get; }
}
`IServiceProvderEngine这个接口`继承了`IServiceProvider`接口,也就是说工作引擎也具有**GetService()**方法,在此接口中具有一个`IServiceScope`类型的**RootScope**,而这个属性则代表是**根容器**

`IServiceScope`代表一个容器接口,这个接口中具有一个`IServiceProvider`类型的属性,返回真正表示容器的一个`IServiceProvider`类型
public interface IServiceScope : IDisposable
{
/// <summary>
/// The <see cref="System.IServiceProvider"/> used to resolve dependencies from the scope.
/// </summary>
IServiceProvider ServiceProvider { get; }
}

IServiceProviderEngine整体结构

IServiceProviderEngine

  • ServiceProviderEngine

    • CompiledServiceProviderEngine

      • DynamicServiceProviderEngine
    • RuntimeServiceProviderEngine
    • ILEmitServiceProviderEngine
    • ExpressionsServiceProviderEngine
上面是目前整个引擎结构,但是前面说过目前只用到了`DynamicServiceProviderEngine`,但是我们看整个类型会看到其实在这几个派生类型中只有一个实现方法`RealizeService(ServiceCallSite callSite)`,而整体结构都是在基类`ServiceProviderEngine`类型中,下面来看看这个基类类型

ServiceProviderEngine

`ServiceProviderEngine`类型是整个结构的核心类型,但是这个类也是一个很简单的类,这个类只是调用`CallSiteFactory`和`CallSiteRuntimeResolver`,由下图可以看到这个类型是一个抽象类,并且实现了`IServiceProviderEngine`和`IServiceScopeFactory`接口接口			

`IServiceScopeFactory`这个接口提供了一个创建子容器方法我们已知道`IServiceProviderEngine`接口*继承*了`IServiceProvider`接口,那么也就是说在`ServiceProviderEngine`已经具备以下两个功能

1.获取服务实例对象

2.创建子容器

internal abstract class ServiceProviderEngine : IServiceProviderEngine, IServiceScopeFactory{}

//		创建子容器接口
public interface IServiceScopeFactory
{
//
IServiceScope CreateScope();
}

下面首先来看一下此类中拥有的字段+属性,这些属性都是在构造器中进行了实例化

  • _callback:

    这个字段就是顶级容器时检查scoped生命周期的访问者对象,这个从ServiceProvider类中时进行传入的,在这里并不细讲这个类型

  • RealizedServices:

    这个属性是缓存根据容器获取服务实例对象委托,其中Key为ServiceType

  • _createServiceAccessor:

    这是一个根据类型获取一个根据容器获取服务实例对象的委托,可以看到使用了一个CreateServiceAccessor()进行赋值,CreateServiceAccessor()是此类型的一个核心方法,下面介绍

  • CallSiteFactory:

    ServiceCallSite工厂类型,在构造器中实例化,可以看到实例化时将serviceDescriptors进行传入,并且可以看到在构造器中向此实例对象中添加了一个IServiceProviderIServiceScopeFactory

  • RuntimeResolver:

    这个属性是是获取服务实例的访问者对象,可以看到在构造器中进行传入

  • Root:

    Root代表是一个顶级容器ServiceProviderEngineScope类型则是一个具体的容器类型,这个类型中缓存了所有的具体服务实例对象,这个类型实现了IServiceScope接口,从下面代码可以看到RootScope其实就是直接返回了Root属性

  • RootScope:

    这也是一个根容器实例对象,直接返回的Root属性

//      顶级容器时scoped生命周期实例检查策略
private readonly IServiceProviderEngineCallback _callback;
// 根据类型创建构建服务的委托
private readonly Func<Type, Func<ServiceProviderEngineScope, object>> _createServiceAccessor;
// 此实例是否被销毁
private bool _disposed; // 缓存根据容器获取服务实例的委托, Key为注册类型
internal ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>> RealizedServices { get; } // CallSite工厂类属性,此类型用于根据指定实例化方式来创建对应的CallSite
internal CallSiteFactory CallSiteFactory { get; }
// 访问者对象,此对象对进行实例和缓存具体真正的对象
protected CallSiteRuntimeResolver RuntimeResolver { get; } // 根容器实例属性
public ServiceProviderEngineScope Root { get; }
// 根容器实例属性
public IServiceScope RootScope => Root; // 构造器
protected ServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback)
{
_createServiceAccessor = CreateServiceAccessor;
_callback = callback;
// 实例化根容器
Root = new ServiceProviderEngineScope(this);
// 实例化 CallSite对象访问者对象
RuntimeResolver = new CallSiteRuntimeResolver(); // 实例化CallSiteFactory类型对象
CallSiteFactory = new CallSiteFactory(serviceDescriptors);
CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite());
// 缓存一个ServiceScopeFactoryCallSite服务,相当于缓存一个ServiceProviderEngine,根据此对象进行创建子容器
CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite());
// 缓存实例化对象的工厂
RealizedServices = new ConcurrentDictionary<Type, Func<ServiceProviderEngineScope, object>>();
}
`ServiceProviderEngine`类型中方法只有**GetService()**,**CreateScope()**,**CreateServiceAccessor()**,**Dispose()**和一个抽象方法**RealizeService()**,其中几个派生类中都只是实现了**RealizeService()**,这个一会再看,下面来看看`ServiceProviderEngine`类中的这几个方法
  • RealizeService:

    这个方法由派生类继承,由指定的ServiceCallSite缓存并获取 服务实例的委托

  • GetService:

    这个方法获取服务实例对象,可以看到具有两个此方法,并且第一个调用了第二个,并将顶级容器Root进行了传入,而在第二个方法中,获取并添加_createServiceAccessor委托,然后调用此委托进行获取服务实例

  • CreateScope:

    这个方法是创建一个子容器对象,在这个方法中可以看到直接 new 了一个容器对象,并将当前对象进行了传入。从此可以得知为什么所有容器共享顶级容器的服务注册了

  • Dispose:

    清除当前对象,并清除顶级容器

  • CreateServiceAccessor:

    这个方法可以看到根据ServiceType进行获取指定ServiceCallSite,然后再调用派生类实现的RealizeService()进行返回

//		抽象类型,子类实现
protected abstract Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite); public object GetService(Type serviceType) => GetService(serviceType, Root); internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
{
if (_disposed)
ThrowHelper.ThrowObjectDisposedException();
// 添加并获取根据容器对象实例化对象的方法,其方法由子类进行重写
var realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor);
// 验证是否允许进行实例化对象
_callback?.OnResolve(serviceType, serviceProviderEngineScope);
return realizedService.Invoke(serviceProviderEngineScope);
}
public void Dispose()
{
_disposed = true;
Root.Dispose();
}
// 实例化的子容器
public IServiceScope CreateScope()
{
if (_disposed)
ThrowHelper.ThrowObjectDisposedException();
return new ServiceProviderEngineScope(this);
}
private Func<ServiceProviderEngineScope, object> CreateServiceAccessor(Type serviceType)
{
// 根据基类类型获取对应的CallSite
var callSite = CallSiteFactory.GetCallSite(serviceType, new CallSiteChain());
if (callSite != null)
{
// 缓存当前注册
_callback?.OnCreate(callSite);
return RealizeService(callSite);
}
return _ => null;
}

DynamicServiceProviderEngine和CompiledServiceProviderEngine

下面来看一下`DynamicServiceProviderEngine`和`CompiledServiceProviderEngine`这两个派生类型,从上面继承关系可以看到这两个派生类型是一个继承关系 `DynamicServiceProviderEngine`继承于`CompiledServiceProviderEngine`.
internal class DynamicServiceProviderEngine : CompiledServiceProviderEngine{}

​在这两个派生类型中都只是实现了基类的RealizeService(),下面先来看看CompiledServiceProviderEngine类的实现

可以看到CompiledServiceProviderEngine类中具有一个ExpressionResolverBuilder对象,这个类是使用表达式树生成结构,这个实例在构造函数进行创建,并且将CallSiteRuntimeResolver对象,本对象和顶级容器进行了传入,可以看到在重写的方法中是调用了ExpressionResolverBuilder对象的Build(),这个方法会生成一个Func<ServiceProviderEngineScope,Object>委托,然后缓存此委托,

注:ExpressionResolverBuilder这个类挺复杂,我也没看懂,所以在此不介绍,有兴趣的可以直接看源码

internal abstract class CompiledServiceProviderEngine : ServiceProviderEngine
{
// 表达式树生成对象
public ExpressionResolverBuilder ExpressionResolverBuilder { get; } // 构造函数
public CompiledServiceProviderEngine(IEnumerable<ServiceDescriptor> serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback)
=> ExpressionResolverBuilder = new ExpressionResolverBuilder(RuntimeResolver, this, Root); // 重写RealizeService方法
protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite)
{
// 使用表达式树进行创建一个Func<ServiceProviderEngineScope,Object>委托
var realizedService = ExpressionResolverBuilder.Build(callSite);
// 直接将表达式生成的委托进行替换之前的缓存
RealizedServices[callSite.ServiceType] = realizedService;
return realizedService;
}
}
而在`RuntimeServiceProviderEngine`类中,则只是实现了**RealizeService()**,从下面代码可以看出在第一次调用时是直接调用`CallSiteRuntimeResolver`这个访问者获取的实例数据,而在第二次才调用的基类,也就是`CompiledServiceProviderEngine`进行了缓存,但是至于为什么这样干,我没有弄清。。。
internal class DynamicServiceProviderEngine : CompiledServiceProviderEngine
{
public DynamicServiceProviderEngine(
IEnumerable<ServiceDescriptor> serviceDescriptors,
IServiceProviderEngineCallback callback)
: base(serviceDescriptors, callback)
{
} protected override Func<ServiceProviderEngineScope, object> RealizeService(ServiceCallSite callSite)
{
var callCount = 0;
return scope =>
{
if (Interlocked.Increment(ref callCount) == 2)
{
// 如果当前是第二次调用,则调用父级进行缓存
Task.Run(() => base.RealizeService(callSite));
}
// 调用访问者进行根据当前容器和CallSite进行实例化服务对象
return RuntimeResolver.Resolve(callSite, scope);
};
}
}

Core官方DI解析(5)-ServiceProviderEngine的更多相关文章

  1. Core官方DI解析(3)-ServiceCallSite.md

    上一篇说过在整个DI框架中IServiceProviderEngine是核心,但是如果直接看IServiceProviderEngine派生类其实看不出也没什么东西,因为这个类型其实都是调用的其它对象 ...

  2. Core官方DI解析(4)--CallSiteRuntimeResolver

    ​ CallSiteRuntimeResolver类型是一个创建或获取服务实例的类型,这个类型继承了CallSiteVisitor<TArgument, TResult>这个类型,也是使用 ...

  3. Core官方DI解析(2)-ServiceProvider

    ServiceProvider ServiceProvider是我们用来获取服务实例对象的类型,它也是一个特别简单的类型,因为这个类型本身并没有做什么,其实以一种代理模式,其核心功能全部都在IServ ...

  4. Core官方DI剖析(1)--ServiceProvider类和ServiceCollection类

    前段时间看了蒋老师的Core文章,对于DI那一块感觉挺有意思,然后就看了一下Core官方DI的源码,这也算是第一个看得懂大部分源码的框架,虽然官方DI相对来说特别简单, 官方DI相对于其它框架(例如 ...

  5. abp vnext2.0核心组件之.Net Core默认DI组件切换到AutoFac源码解析

    老版Abp对Castle的严重依赖在vnext中已经得到了解决,vnext中DI容器可以任意更换,为了实现这个功能,底层架构相较于老版abp,可以说是进行了高度重构.当然这得益于.Net Core的D ...

  6. Asp.Net Core中DI的知识总结

    在asp.net core中DI的概念是由这几部分组成的: IServiceCollection,保存IServiceDescriptor实例的列表 IServiceProvider,只有一个方法Ge ...

  7. asp.net core的DI框架思考以及服务实例的获取方式总结

    转载请注明出处: https://home.cnblogs.com/u/zhiyong-ITNote/ 整个asp.net core管道从WebHostBuilder到WebHost到后续请求的类中, ...

  8. 实战Asp.Net Core:DI生命周期

    title: 实战Asp.Net Core:DI生命周期 date: 2018-11-30 21:54:52 --- 1.前言 Asp.Net Core 默认支持 DI(依赖注入) 软件设计模式,那使 ...

  9. 阅读DMA Controller Core 官方手册

    阅读DMA Controller Core 官方手册 DMA控制器框架图 怎样去设定一个DMA控制器 实例化DMA控制器 参数配置界面如下图所示: 对于width of the DMA length ...

随机推荐

  1. 使用 ASP.NET Core MVC 创建 Web API(四)

    使用 ASP.NET Core MVC 创建 Web API 使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使 ...

  2. Python编程从入门到实践笔记——用户输入和while循环

    Python编程从入门到实践笔记——用户输入和while循环 #coding=utf-8 #函数input()让程序暂停运行,等待用户输入一些文本.得到用户的输入以后将其存储在一个变量中,方便后续使用 ...

  3. Python编程从入门到实践笔记——变量和简单数据类型

    Python编程从入门到实践笔记——变量和简单数据类型 #coding=gbk #变量 message_1 = 'aAa fff' message_2 = 'hart' message_3 = &qu ...

  4. MariaDB Galera集群部署--技术流ken

    Galera集群介绍 MariaDB集群是MariaDB同步多主机集群.它仅支持XtraDB/ InnoDB存储引擎. 主要功能 同步复制 真正的multi-master,即所有节点可以同时读写数据库 ...

  5. 系统检测工具ROSWTF

    ROSWTF 详细见http://wiki.ros.org/roswtf roswtf will examine your ROS setup, such as your environment va ...

  6. MVC中使用Ninject依赖注入

    在.NET MVC中使用Ninject注入,主要分为以下几步: 使用NuGet包添加Ninject引用,我添加的是目前最新版本3.34 在App_Start文件夹下,创建NinjectControll ...

  7. [转]Python in Visual Studio Code

    本文转自:https://code.visualstudio.com/docs/languages/python Working with Python in Visual Studio Code, ...

  8. ASP.NET Core 基于JWT的认证(二)

    ASP.NET Core 基于JWT的认证(二) 上一节我们对 Jwt 的一些基础知识进行了一个简单的介绍,这一节我们将详细的讲解,本次我们将详细的介绍一下 Jwt在 .Net Core 上的实际运用 ...

  9. ConcurrentHashMap1.8源码分析

    文章简介 想必大家对HashMap数据结构并不陌生,JDK1.7采用的是数组+链表的方式,JDK1.8采用的是数组+链表+红黑树的方式.虽然JDK1.8对于HashMap有了很大的改进,提高了存取效率 ...

  10. 高并发系统保护~ing

    由于公司业务发展,需要考虑一些高并发系统保护的问题,整理记录一下. 当发现你的系统出现访问卡顿,服务器各种性能指标接近100%(如果一个初创型企业系统正常运行情况下出现这个问题,那么应该恭喜你,你懂得 ...