返回首页 | 新开户送体验金的娱乐城

合作共赢、快速高效、优质的网站建设提供商

更多精品源码-尽在织梦模板-www.moke8.com

网站开发解析 .Net Core 注入 (2) 创立容器

时间:2017-10-23 编辑:admin

在上一节的学习中,我们们现已知道了经过 IServiceCollection 拓宽挑选创立 IServiceProvider 默许的是一个类型为 ServiceProvider 目标,而且实践供给创立目标功用的是它的内部为类型为 IServiceProviderEngine 目标,实践上关于 IServiceProvider 的架构比我们们幻想的还要杂乱的多,一个是根容器的概念,另一个就是运用编译时引擎动态构建表达式树,提高了创立实例的功率。

容器、引擎和根容器

在这张类图中,有三个中心接口,IServiceProvider 表明容器,具有供给目标功用,IServiceScope 代表一个具有规模的节点容器,而 IServiceProviderEngine 是供给目标中心接口,具有一个根容器,每次创立目标的时分都会带上具有规模的节点容器。关于容器和引擎这两个概念怎么判别呢?但凡完成了 IServiceProvider 的都能够称为容器,相同的,但凡完成了 IServiceProviderEngine 的都能够称为引擎,引擎仍然是一个容器,实践上,上图中一切的类型都是一个容器,由于他们都直接或许直接完成了 IServiceProvider 接口,可是终究担任创立效劳实例的必定是一个引擎!

public interface IServiceProvider
 object GetService(Type serviceType);
public interface IServiceScope : IDisposable
 IServiceProvider ServiceProvider { get; }
internal interface IServiceProviderEngine : IDisposable, IServiceProvider
 IServiceScope RootScope { get; }
}
ServiceProviderEngineScope

IServiceScope 的默许完成是 ServiceProviderEngineScope,ResolvedServices 存储现已实例化过的生命周期为 Scoped 的目标,_disposables 存储经过该根创立的一切实例类型,在调用 Dispose 挑选时会开释 _disposables 中的目标,一起清空 ResolvedServices 中的实例。

internal class ServiceProviderEngineScope : IServiceScope, IServiceProvider
 private List IDisposable _disposables = new List IDisposable ();
 public ServiceProviderEngineScope(ServiceProviderEngine engine)
 Engine = engine;
 internal Dictionary object, object ResolvedServices { get; } = new Dictionary object, object ();
 public ServiceProviderEngine Engine { get; }
 public object GetService(Type serviceType)
 return Engine.GetService(serviceType, this);
 public IServiceProvider ServiceProvider = this;
 //省掉了一些代码
}

ServiceProviderEngineScope 总在引擎被创立的时分初始化,而且在 GetService 挑选中,传递的根容器正是这个 Root,所以根容器一般状况不会更改,可是我们们能够 CreateScope 挑选来创立一个新的根容器,实践上到这儿可能仍是很难了解这个效果域是怎么构成的,不要紧,后边还会介绍!

internal abstract class ServiceProviderEngine : IServiceProviderEngine, IServiceScopeFactory
 protected ServiceProviderEngine(IEnumerable ServiceDescriptor serviceDescriptors, IServiceProviderEngineCallback callback)
 Root = new ServiceProviderEngineScope(this);
 public object GetService(Type serviceType) = GetService(serviceType, Root);
 public ServiceProviderEngineScope Root { get; }
 public IServiceScope CreateScope()
 return new ServiceProviderEngineScope(this);
}
默许的容器 ServiceProvider ServiceProviderOptions
public static class ServiceCollectionContainerBuilderExtensions
 public static ServiceProvider BuildServiceProvider(this IServiceCollection services)
 return BuildServiceProvider(services, ServiceProviderOptions.Default);
 public static ServiceProvider BuildServiceProvider(this IServiceCollection services, ServiceProviderOptions options)
 return new ServiceProvider(services, options);
public class ServiceProviderOptions
 internal static readonly ServiceProviderOptions Default = new ServiceProviderOptions();
 public bool ValidateScopes { get; set; }
 internal ServiceProviderMode Mode { get; set; } = ServiceProviderMode.Dynamic;
}

我们们知道在 IServiceCollection 的拓宽挑选BuildServiceProvider 终究回来的是一个 ServiceProvider,由于默许的 ServiceProviderMode 是 Dynamic,所以默许状况下,供给效劳的是一个 DynamicServiceProviderEngine 目标,可是它与 CompiledServiceProviderEngine 仅有的差异就是笼统挑选 RealizeService 的完成,前者供给真实的创立目标的挑选,而后者将前者供给的创立目标的挑选翻译成表达式树。

ServiceProvider
public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback
 private readonly IServiceProviderEngine _engine;
 private readonly CallSiteValidator _callSiteValidator;
 internal ServiceProvider(IEnumerable ServiceDescriptor serviceDescriptors, ServiceProviderOptions options)
 IServiceProviderEngineCallback callback = null;
 if (options.ValidateScopes)
 callback = this;
 _callSiteValidator = new CallSiteValidator();
 switch (options.Mode)
 case ServiceProviderMode.Dynamic:
 _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback);
 break;
 case ServiceProviderMode.Runtime:
 _engine = new RuntimeServiceProviderEngine(serviceDescriptors, callback);
 break;
 case ServiceProviderMode.Compiled:
 _engine = new CompiledServiceProviderEngine(serviceDescriptors, callback);
 break;
 default:
 throw new ArgumentOutOfRangeException(nameof(options.Mode));
}

由于ServiceProviderOptions.Default 供给的参数中 ValidateScoped 默许值是 False,所以这儿不计划介绍 IServiceProviderEngineCallback 以及 CallSiteValidator 这两个类型。依据参数 option 的 Mode 为 Dynamic,创立了一个类型为 DynamicServiceProviderEngine 的引擎,实践上该引擎是怎么创立目标是后续要讲的,这儿我们们只重视它的创立进程,所以我们们又来到了 ServiceProviderEngine 的结构函数。

ServiceProviderEngine
internal abstract class ServiceProviderEngine : IServiceProviderEngine, IServiceScopeFactory
 protected abstract Func ServiceProviderEngineScope, object RealizeService(IServiceCallSite callSite);
 internal ConcurrentDictionary Type, Func ServiceProviderEngineScope, object RealizedServices { get; } =
 new ConcurrentDictionary Type, Func ServiceProviderEngineScope, object ();
 private readonly Func Type, Func ServiceProviderEngineScope, object _createServiceAccessor;
 protected ServiceProviderEngine(IEnumerable ServiceDescriptor serviceDescriptors, IServiceProviderEngineCallback callback)
 _createServiceAccessor = CreateServiceAccessor;
 _callback = callback;
 Root = new ServiceProviderEngineScope(this);
 RuntimeResolver = new CallSiteRuntimeResolver();
 ExpressionBuilder = new CallSiteExpressionBuilder(RuntimeResolver, this, Root);
 CallSiteFactory = new CallSiteFactory(serviceDescriptors);
 CallSiteFactory.Add(typeof(IServiceProvider), new ServiceProviderCallSite());
 CallSiteFactory.Add(typeof(IServiceScopeFactory), new ServiceScopeFactoryCallSite());
 private readonly IServiceProviderEngineCallback _callback;
 internal CallSiteFactory CallSiteFactory { get; }
 protected CallSiteRuntimeResolver RuntimeResolver { get; }
 protected CallSiteExpressionBuilder ExpressionBuilder { get; }
 public ServiceProviderEngineScope Root { get; }
 public IServiceScope RootScope = Root;
 private Func ServiceProviderEngineScope, object CreateServiceAccessor(Type serviceType)
 var callSite = CallSiteFactory.CreateCallSite(serviceType, new CallSiteChain());
 if (callSite != null)
 _callback?.OnCreate(callSite);
 return RealizeService(callSite);
 return _ = null;
 }

这是一个笼统类,还记得我们们前面提起过得 IServiceCallSite 吗?它是创立效劳实例的依据,虽然还没有得到证明,可是我们们要深信!然后我们们看笼统挑选 RealizeService,它是一个挑选,供给一个托付,该托付承受一个根容器,然后回来一个实例目标,可能有点绕,简而言之这个笼统挑选供给一个挑选,该挑选能够完成效劳实例的创立!

internal class DynamicServiceProviderEngine : CompiledServiceProviderEngine
 public DynamicServiceProviderEngine(IEnumerable ServiceDescriptor serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback)
 protected override Func ServiceProviderEngineScope, object RealizeService(IServiceCallSite callSite)
 var callCount = 0;
 return scope = 
 if (Interlocked.Increment(ref callCount) == 2)
 Task.Run(() = base.RealizeService(callSite));
 return RuntimeResolver.Resolve(callSite, scope);
}

如果我们们对该笼统挑选回来的托付了解了,那也会很简单了解字典RealizedServices,和那个托付一样,这个字典存储的是每个效劳类型的创立实例的挑选,相同的,托付_createServiceAccessor 也很好了解。关于 CallSiteRuntimeResolver,这儿只需求知道在 DynamicServiceProviderEngine 完成的 RealizeService 挑选中,最终回来的托付是依据它来解析 IServiceCallSite 来创立实例的!CallSiteExpressionBuilder 这个类型是在CompiledServiceProviderEngine中完成将创立实例的进程构建成表达式树的,详细进程后续讲,可是这儿需求知道关于同一个效劳,创立其实例的进程应当总是共同的,而这个进程就保存在 RealizedServices 中,而实践创立实例的进程在 DynamicServiceProviderEngine 中,我们们在DynamicServiceProviderEngine 的 RealizeService 挑选中发现,如果是第2次创立该实例,则会调用父类 CompiledServiceProviderEngine 的 RealizeService 挑选,而且它是以异步方法履行的,虽然如此,最终创立实例的挑选仍然是 DynamicServiceProviderEngine 供给的托付,可是CompiledServiceProviderEngine 的 RealizeService 挑选做了些什么呢?

internal class CompiledServiceProviderEngine : ServiceProviderEngine
 public CompiledServiceProviderEngine(IEnumerable ServiceDescriptor serviceDescriptors, IServiceProviderEngineCallback callback) : base(serviceDescriptors, callback)
 protected override Func ServiceProviderEngineScope, object RealizeService(IServiceCallSite callSite)
 var realizedService = ExpressionBuilder.Build(callSite);
 RealizedServices[callSite.ServiceType] = realizedService;
 return realizedService;
}

实践上这儿回来的 realizedService 永久都不会得到调用,可是这个托付却永久的替换了 RealizedServices 中的某个托付,而新的以表达式树构建的托付是怎么地调调用的呢?

internal object GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
 var realizedService = RealizedServices.GetOrAdd(serviceType, _createServiceAccessor);
 _callback?.OnResolve(serviceType, serviceProviderEngineScope);
 return realizedService.Invoke(serviceProviderEngineScope);
}

我们们看到在ServiceProviderEngine 的 GetService 挑选中,只需 RealizedServices 中现已存在该效劳的创立实例的托付就不会经过CreateServiceAccessor 再去调用笼统挑选获取托付,也就是说被CompiledServiceProviderEngine 履行它自己的RealizeService 挑选后,今后创立该效劳的实例目标总是经过表达式树创立的。

在这一节中,我们们学习了容器创立进程中的一些中心类型,可是最中心的仍然在 ServiceProviderEngine 这个笼统类中,虽然供给了笼统挑选 RealizeService 答应子类供给创立实例的托付,可是创立实例的详细逻辑仍然有它自己的CallSiteRuntimeResolver 供给,再加上创立实例的挑选一直都是经过托付供给的,所以使得 DynamicServiceProviderEngine 和 CompileServiceProviderEngine 这两个类十分的简练,可是仍然对 DynamicServiceProviderEngine 是怎么运用CallSiteRuntimeResolver创立实例的,CompileServiceProviderEngine 又是怎么构建表达式树的,效果域又是怎么构成的,由于这些都和 IServiceCallSite 有离不开的联系。


浏览:

网站建设

流程

    网站建设流程