前言
在采用了依賴注入的應用中,我們總是直接利用DI容器直接獲取所需的服務實例,換句話說,DI容器起到了一個服務提供者的角色,它能夠根據我們提供的服務描述信息提供一個可用的服務對象。ASP.NET Core中的DI容器體現為一個實現了IServiceProvider接口的對象。
ServiceProvider與ServiceDescriptor
服務的注冊與提供
利用ServiceProvider來提供服務
提供一個服務實例的集合
獲取ServiceProvider自身對象
對泛型的支持
一、ServiceProvider與ServiceDescriptor
我一直覺得優秀的設計首先應該是簡單的設計,至少是看起來簡單的設計,這就是我們所謂的大道至簡。作為一個服務的提供者,ASP.NET Core中的DI容器最終體現為一個IServiceProvider接口,我們將所有實現了該接口的類型及其實例統稱為ServiceProvider。如下面的代碼片段所示,該接口簡單至極,它僅僅提供了唯一個GetService方法,該方法根據提供的服務類型為你提供對應的服務實例。
public interface IServiceProvider { object GetService(Type serviceType); }ASP.NET Core內部真正使用的是一個實現了IServiceProvider接口的內部類型(該類型的名稱為“ServiceProvider”),我們不能直接創建該對象,只能間接地通過調用IServiceCollection接口的擴展方法BuildServiceProvider得到它。IServiceCollection接口定義在“Microsoft.Extensions.DependencyInjection”命名空間下,如果沒有特別說明,本系列文章涉及到的與ASP.NET Core依賴注入相關的類型均采用此命名空間。 如下面的代碼片段所示,IServiceCollection接口實際上代表一個元素為ServiceDescriptor對象的集合,它直接繼承了另一個接口IList<ServiceDescriptor>,而ServiceCollection類實現了該接口。
public static class ServiceCollectionExtensions { public static IServiceProvider BuildServiceProvider(this IServiceCollection services); } public interface IServiceCollection : IList<ServiceDescriptor> {} Public class ServiceCollection: IServiceCollection { //省略成員 }體現為DI容器的ServiceProvider之所以能夠根據我們給定的服務類型(一般是一個接口類型)提供一個能夠開箱即用的服務實例,是因為我們預先注冊了相應的服務描述信息,這些指導ServiceProvider正確實施服務提供操作的服務描述體現為如下一個ServiceDescriptor類型。
public class ServiceDescriptor { public ServiceDescriptor(Type serviceType, object instance); public ServiceDescriptor(Type serviceType, Func<IServiceProvider, object> factory, ServiceLifetime lifetime); public ServiceDescriptor(Type serviceType, Type implementationType, ServiceLifetime lifetime); public Type ServiceType { get; } public ServiceLifetime Lifetime { get; } public Type ImplementationType { get; } public object ImplementationInstance { get; } public Func<IServiceProvider, object> ImplementationFactory { get; } }
新聞熱點
疑難解答
圖片精選