ServiceProvider
是咱们用来获取服务实例对象的类型,它也是一个特别简单的类型,由于这个类型自己并无作什么,其实以一种代理模式,其核心功能所有都在IServiceProviderEngine
实现类中c#
ServiceProvider
还具备一个扩展类型ServiceProviderServiceExtensions
,在扩展类型之中实现了一些咱们常常使用的获取服务实例方法,好比GetServices()
和GetRequiredService()
方法,还实现了获取子容器方法CreateScope()
,下面来具体的看一下这个类型缓存
从下面代码看到ServiceProvider
一个实现了三个接口ide
- IServiceProvider 获取服务接口,这个接口是位于
System
程序集下的,而这个接口只有一个object GetService(Type serviceType)
方法,也就是说咱们经常使用不少方法包括泛型获取都是来自于扩展类中- IDisposable 说明此对象须要被释放
- IServiceProviderEngineCallback 这个接口就是检验
validateScopes
时使用的,接口具备两个方法OnCreate()和OnResolve()分别用于建立服务实例时缓存和校验,
public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback {}
ServiceProvider
这个类型其实挺简单,从下面代码中GetService()方法能够看出它只是代理了一个IServiceProviderEngine
实现类型,函数
_engine: 做为一个
IServiceProviderEngine
接口,这个接口是ServiceProvider
的工做引擎接口,也是一个核心类型,下一章再详细讲解这个接口及其实现类型ui_callSiteValidator: 这是一个验证ValidateScopes的缓存类型(访问者模式),能够看到,在构造函数中只有当ValidateScopes为true时才实例化此对象,而后在获取服务实例时经过OnCreate()进行缓存和经过OnResolve()进行校验this
ServiceProvider
的实例化方式在上一章已经说过,利用ServiceDescriptor
集合和ServiceProviderOptions
进行实例化,能够看到,在构造方法中首先经过ValidateScopes属性来进行实例化CallSiteValidator
和将当前对象赋值给IServiceProviderEngineCallback
类型变量代理
将this赋值给IServiceProviderEngineCallback是为了让IServiceProviderEngine进行调用验证code
而后经过ServiceProviderMode这个枚举进行判断实例化的具体引擎对象,四个枚举对应四种引擎对象,前面已经说过目前DI只使用了Dynamic这一种,下面说IServiceProviderEngineCallback时也只说这一种orm
public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback { // ServiceProvider工做引擎接口 // 这个接口是一个核心接口 // 使用这个接口的子类进行调用缓存各类注册服务和调用访问者对象进行获取实例对象 private readonly IServiceProviderEngine _engine; /// 此属性缓存当前注册类型,当ServiceProviderOptions.ValidateScopes为true进行验证 private readonly CallSiteValidator _callSiteValidator; internal ServiceProvider(IEnumerable<ServiceDescriptor> serviceDescriptors, ServiceProviderOptions options) { IServiceProviderEngineCallback callback = null; if (options.ValidateScopes) { callback = this; _callSiteValidator = new CallSiteValidator(); } // 根据ServiceProviderMode进行实例化对应的工做引擎类型 switch (options.Mode) { case ServiceProviderMode.Dynamic: // 实例化 DynamicServiceProviderEngine _engine = new DynamicServiceProviderEngine(serviceDescriptors, callback); break; case ServiceProviderMode.Runtime: _engine = new RuntimeServiceProviderEngine(serviceDescriptors, callback); break; case ServiceProviderMode.ILEmit: _engine = new ILEmitServiceProviderEngine(serviceDescriptors, callback); break; case ServiceProviderMode.Expressions: _engine = new ExpressionsServiceProviderEngine(serviceDescriptors, callback); break; default: throw new NotSupportedException(nameof(options.Mode)); } } /// 获取指定类型的服务对象 public object GetService(Type serviceType) => _engine.GetService(serviceType); public void Dispose() => _engine.Dispose(); void IServiceProviderEngineCallback.OnCreate(ServiceCallSite callSite) =>_callSiteValidator.ValidateCallSite(callSite); void IServiceProviderEngineCallback.OnResolve(Type serviceType, IServiceScope scope) =>_callSiteValidator.ValidateResolution(serviceType, scope, _engine.RootScope); }
前面说过这个类是ServiceProvider
的扩展类型,提供了更佳便捷,下面就来看看这个这个扩展类提供的方法对象
在这个扩展类中就扩展了GetRequiredService(),GetServices()和CreateScope()三个方法,前两个也是获取服务实例,第三个获取一个子IServiceProvider
,也就是说获取一个子容器
GetRequiredService()方法是若是获取的当前类型并无被注册,那么就会抛出InvalidOperationException
异常,从下面代码能够看出,GetRequiredService()方法首先判断当前ServicePrivider
是不是ISupportRequiredService
的实现类,若是是,则就返回自身的GetRequiredService()方法,若是不是,就直接调用GetService(),若是返回服务实例为NULL,就抛出异常.
ISupportRequiredService
接口中只定义了GetRequiredService(),然而如今的ServiceProvider
类型并无实现ISupportRequiredService
接口
GetServices()方法是获取当前类型的全部服务实例,能够看到这个方法无非是调用的GetRequiredService(),只不过参数是一个IEnumerable
CreateScope()方法是一个获取子类容器的,获取方式从下面代码看的也是经过服务注册的方式获取服务实例,也就是说内部进行了注册,这个注册是在ServiceProviderEngine
类中
public static class ServiceProviderServiceExtensions { // 泛型重载 public static T GetService<T>(this IServiceProvider provider) => (T)provider.GetService(typeof(T)); // 若是当前服务并未注册,则会抛出异常 public static object GetRequiredService(this IServiceProvider provider, Type serviceType) { // 若是当前ServiceProvider实现了 ISupportRequiredService // 则直接调用当前ServiceProvier的GetRequiredService获取服务实例 var requiredServiceSupportingProvider = provider as ISupportRequiredService; if (requiredServiceSupportingProvider != null) return requiredServiceSupportingProvider.GetRequiredService(serviceType); // 若是当前ServiceProvider未实现ISupportRequiredService // 就直接调用GetService获取服务实例,可是若是服务实例为空,则抛出异常 var service = provider.GetService(serviceType); if (service == null) throw new InvalidOperationException(Resources.FormatNoServiceRegistered(serviceType)); return service; } // 泛型版本 public static T GetRequiredService<T>(this IServiceProvider provider) => (T)provider.GetRequiredService(typeof(T)); // 获取指定注册类型<T>的全部服务实例 public static IEnumerable<T> GetServices<T>(this IServiceProvider provider) => provider.GetRequiredService<IEnumerable<T>>(); // 同上, public static IEnumerable<object> GetServices(this IServiceProvider provider, Type serviceType) { // 制造一个serviceType类型的IEnumberable<>集合,serviceTypele类型做为当前集合的泛型参数 var genericEnumerable = typeof(IEnumerable<>).MakeGenericType(serviceType); return (IEnumerable<object>)provider.GetRequiredService(genericEnumerable); } // 建立一个子IServiceProvider实例 // 内部其实将IServiceScopeFactory接口和一个ServiceScopeFactoryCallSite进行了注册 // 这个是在IServiceProviderEngine的实现类ServiceProviderEngine中的,之后在详细介绍 public static IServiceScope CreateScope(this IServiceProvider provider) => provider.GetRequiredService<IServiceScopeFactory>().CreateScope(); }