對於依賴注入,常用的是通過構造函數注入對象,寫法有時太繁瑣,本篇介紹通過手動方式進行注入,在用法上更加方便些。
========== 原創作品 作者:未聞 出處:博客園 ==========
一、先了解依賴注入的幾個生命周期
* Scoped:同一個Request請求使用同一個實例。
* Transient:瞬時,即每次注入、GetService都是新的實例。
* Singleton:單例模式,應用程序共享同一實例。
二、理論知識
* Startup.Configure函數中得到app.ApplicationServices,可以通過它的GetService方法獲得Transient、Singleton的對象。
* 可以通過HttpContextAccessor對象的HttpContext.RequestServices.GetService方法獲得Scoped的對象。
* 可以通過app.ApplicationServices.GetService<IHttpContextAccessor>()獲得HttpContextAccessor對象。
三、具體實現步驟
1. 定義靜態變量
public static IServiceProvider ServiceProvider { get; set; }
2. 在Startup的Configure方法中給ServiceProvider賦值
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //... GlobalContext.ServiceProvider = app.ApplicationServices; }
3. 在Startup的ConfigureServices方法中啟用HttpContextAccessor
public void ConfigureServices(IServiceCollection services) { //... services.AddHttpContextAccessor();// 支持IHttpContextAccessor }
4. 提供靜態方法GetService<T>,完整示例代碼
/// <summary> /// 全局上下文 /// </summary> public static class GlobalContext { /// <summary> /// 注入對象服務提供類 /// </summary> public static IServiceProvider ServiceProvider { get; set; } /// <summary> /// 手動獲取注入的對象 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public static T GetService<T>() where T : class { return ServiceProvider?.GetService<IHttpContextAccessor>()?.HttpContext.RequestServices.GetService<T>(); } }
5. 調用示例
public interface IDependency { } public abstract class BaseService<T> : IDependency where T : class, IDBContext { protected SqlSugarClient _db => GlobalContext.GetService<T>().Client; } public class AuthService : BaseService<ISoye360DBContext> { public bool IsClientExists(string clientId) { return _db.Queryable<Client>().First(c => c.ID == clientId && c.Enable) != null; } }