日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Core官方DI解析(2)-ServiceProvider

發布時間:2025/3/14 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Core官方DI解析(2)-ServiceProvider 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ServiceProvider

ServiceProvider是我們用來獲取服務實例對象的類型,它也是一個特別簡單的類型,因為這個類型本身并沒有做什么,其實以一種代理模式,其核心功能全部都在IServiceProviderEngine實現類中

ServiceProvider還具有一個擴展類型ServiceProviderServiceExtensions,在擴展類型之中實現了一些我們經常使用的獲取服務實例方法,比如GetServices()和GetRequiredService()方法,還實現了獲取子容器方法CreateScope(),下面來具體的看一下這個類型

從下面代碼看到ServiceProvider一個實現了三個接口

  • IServiceProvider 獲取服務接口,這個接口是位于System程序集下的,而這個接口只有一個object GetService(Type serviceType)方法,也就是說我們常用很多方法包括泛型獲取都是來自于擴展類中
  • IDisposable 說明此對象需要被釋放
  • IServiceProviderEngineCallback 這個接口就是檢驗validateScopes時使用的,接口具有兩個方法OnCreate()OnResolve()分別用于創建服務實例時緩存和校驗,?
public sealed class ServiceProvider : IServiceProvider, IDisposable, IServiceProviderEngineCallback {}

? ServiceProvider這個類型其實挺簡單,從下面代碼中GetService()方法可以看出它只是代理了一個IServiceProviderEngine實現類型,

**_engine**: 作為一個IServiceProviderEngine接口,這個接口是ServiceProvider的工作引擎接口,也是一個核心類型,下一章再詳細講解這個接口及其實現類型

**_callSiteValidator: 這是一個驗證ValidateScopes的緩存類型(訪問者模式),可以看到,在構造函數中只有當ValidateScopes為true時才實例化此對象,然后在獲取服務實例時通過OnCreate()進行緩存和通過OnResolve()**進行校驗

? ServiceProvider的實例化方式在上一章已經說過,利用ServiceDescriptor集合和ServiceProviderOptions進行實例化,可以看到,在構造方法中首先通過ValidateScopes屬性來進行實例化CallSiteValidator和將當前對象賦值給IServiceProviderEngineCallback類型變量

this賦值給IServiceProviderEngineCallback是為了讓IServiceProviderEngine進行調用驗證

? 然后通過ServiceProviderMode這個枚舉進行判斷實例化的具體引擎對象,四個枚舉對應四種引擎對象,前面已經說過目前DI只使用了Dynamic這一種,下面說IServiceProviderEngineCallback時也只說這一種

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); }

ServiceProviderServiceExtensions

? 前面說過這個類是ServiceProvider的擴展類型,提供了更佳便捷,下面就來看看這個這個擴展類提供的方法

?

? 在這個擴展類中就擴展了GetRequiredService(),GetServices()CreateScope()三個方法,前兩個也是獲取服務實例,第三個獲取一個子IServiceProvider,也就是說獲取一個子容器

?

? GetRequiredService()方法是如果獲取的當前類型并沒有被注冊,那么就會拋出InvalidOperationException異常,從下面代碼可以看出,GetRequiredService()方法首先判斷當前ServicePrivider是否是ISupportRequiredService的實現類,如果是,則就返回自身的GetRequiredService()方法,如果不是,就直接調用GetService(),如果返回服務實例為NULL,就拋出異常.

ISupportRequiredService接口中只定義了GetRequiredService(),然而現在的ServiceProvider類型并沒有實現ISupportRequiredService接口

? GetServices()方法是獲取當前類型的所有服務實例,可以看到這個方法無非是調用的GetRequiredService(),只不過參數是一個IEnumerable集合,在內部使用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(); }

轉載于:https://www.cnblogs.com/yan7/p/10024341.html

總結

以上是生活随笔為你收集整理的Core官方DI解析(2)-ServiceProvider的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。