以前在隨筆《Winform開發框架之客戶關係管理系統(CRM)的開發總結系列1-界面功能展示 》的幾篇隨筆中介紹過基於WInform開發框架開發的CRM系統,系統的功能主要也是圍繞著客戶相關信息來進行管理的。本篇隨筆介紹在最新的《SqlSugar開發框架》中整合CRM系統模塊的功能。 ...
IOC 容器內保存的程式運行過程中使用的服務實例。那麼如果有些服務實例需要在運行時動態生成,比如,資料庫連接,不可能在程式運行過程中所有線程共用一條資料庫連接。所以 IOC 容器內保存的不是具體的服務實例,而是服務的相關信息,使用這個信息可以在程式運行時動態的生成服務實例,這些信息就保存在 ServiceDescriptor 類型的對象中。
屬性
//生命周期
//Singleton 容器內有且只有一份
//Scope 範圍內只有一份,範圍 可以使用 ServicePorvider.CreateScope 創建(可以將容器理解成樹狀結構每個Scope就是一個子容器),最常見的範圍就是 Http 請求,每個請求算一個範圍
//Trasient 每次從IOC容器獲取都是新的實例
public ServiceLifetime Lifetime { get; }
//介面類型 介面類型和實現類型可以相同
public Type ServiceType { get; }
//實現類型
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)]public Type? ImplementationType { get; }
//實現實例
public object? ImplementationInstance { get; }
//實現類型工廠
public Func<IServiceProvider, object>? ImplementationFactory { get; }
構造函數
- private 構造函數
先介紹一個 private 的構造函數,個人認為這個構造函數設計為private有兩個原因
- 實例化出來的所有 ServiceDescriptor 對象都具有 serviceType 和 lifetime,所以這兩個屬性的賦值可以被單獨剝離
- 由於所有 ServiceDescriptor 必須要描述服務實例的構造方式,所以不能允許外部直接調用這個構造函數生成ServiceDescriptor實例,所以是 private 的
- public 構造函數
根據服務的生命周期和生成方式有三種不同的 public 的構造函數。
- Singleton
public ServiceDescriptor( Type serviceType,object instance)
: this(serviceType, ServiceLifetime.Singleton)
{
//.....
ImplementationInstance = instance;
}
- Scope 和 Trasient
- 通過註入的實例類型通過反射獲取
public ServiceDescriptor(Type serviceType,Type implementationType,ServiceLifetime lifetime)
: this(serviceType, lifetime)
{
// ....
ImplementationType = implementationType;
}
-
- 通過傳入的 構造工廠(委托)獲取
public ServiceDescriptor(
Type serviceType, //服務類型
Func<IServiceProvider, object> factory, //創建服務的工廠
ServiceLifetime lifetime //服務的生命周期
): this(serviceType, lifetime)
{
ImplementationFactory = factory;
}
方法
ServiceDescriptor 里的方法都是靜態方法,用於生成 ServiceDescriptor 實例。
核心 是要獲取 註入的介面類型 和 實例類型或者生成實例的工廠,所以調用 Describe 方法之後,最終還是兩個方法,一個保存了 介面類型和實例類型,一個保存了 介面類型和生成實例的工廠(),下麵貼出來的是生成 Trasient 的 ServcieDescriptor 的方法,生成 Scope 和 Singleton 的與之類似
//使用TService, TImplementation 生成 ServiceDescriptor(Transient)
// TService 介面類型
// TImplementation 實現類型 繼承 TService
public static ServiceDescriptor Transient
<TService, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] TImplementation>()
where TService : class
where TImplementation : class, TService
{
return Describe<TService, TImplementation>(ServiceLifetime.Transient);
}
// service 介面類型
// implementationType 實現類型
// lifetime 生命周期
public static ServiceDescriptor Describe(
Type serviceType,
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] Type implementationType, ServiceLifetime lifetime
)
{
return new ServiceDescriptor(serviceType, implementationType, lifetime);
}