談到服務注冊,首先我們先了解一下服務注冊時使用的三種方式,也代表了不同的服務生命周期:
1 AddTransient 2 AddScoped 3 AddSingleton
AddSingleton生命周期最長,其生命周期范圍描述為:從應用程序啟動到應用程序結束。在第一次請求時會創建一個實例,之后的每次請求都會使用同一個實例。
AddTransient生命周期最短,在服務請求時會創建一個實例,服務請求結束生命周期即結束,之后的每一次請求都會創建不同的實例。
AddScoped生命周期介於上述兩者之間,這里用客戶端請求會話的概念來描述比較清晰一點,它也是在服務請求時創建實例,但是在同一個會話周期內,之后的每次請求都會使用同一個實例,直至會話結束才會創建新的實例。
ASP.Net Core框架支持我們以如下方式注冊我們自己的服務。
services.AddScoped<ITest, Test>();
其中第一個泛型類型(如:ITest)表示將要從容器中請求的類型(通常是一個接口)。第二個泛型類型(如:Test)表示將由容器實例化並且用於完成這些請求的具體實現類。
具體我們一起看下面的例子:
首先,我們創建一個需要實現查詢功能的服務接口ITest
public interface ITest { Task<string> Get(); }
然后,我們創建功能類Test實現這個接口
1 public class Test : ITest 2 { 3 private readonly ILogger logger; 4 public Test(ILogger<Test> _logger) 5 { 6 logger = _logger; 7 } 8 public Task<string> Get() 9 { 10 logger.LogInformation("自定義服務查詢"); 11 return Task.FromResult("Hello World"); 12 } 13 }
最后,我們需要我們自己的服務注冊到容器中。
public void ConfigureServices(IServiceCollection services) { services.AddScoped<ITest, Test>(); }
以上我們便簡單完成了自定義服務的注冊。
隨后我這里創建了一個Controller用以使用該服務。
1 [Route("api/[controller]")] 2 [ApiController] 3 public class ValuesController : ControllerBase 4 { 5 //聲明服務 6 private readonly ITest service; 7 8 /// <summary> 9 /// 通過構造函數的方式注入自定義服務類 10 /// </summary> 11 /// <param name="_service"></param> 12 public ValuesController(ITest _service) 13 { 14 service = _service; 15 } 16 17 /// <summary> 18 /// 調用服務中實現的Get方法 19 /// </summary> 20 /// <returns></returns> 21 [HttpGet] 22 public Task<string> Get() 23 { 24 return service.Get(); 25 } 26 }
ASP.Net Core框架默認支持我們以構造函數的方式注入我們的服務以使用。
我想寫到這里,大家也會有疑問,如果我們有很多service,這樣一個個注冊寫起來代碼很低效,這里我們簡單給大家介紹一種批量注冊的方式:
這里我們創建了一個批量注冊服務派生類:
1 public static class ServiceExtensions 2 { 3 /// <summary> 4 /// 批量注冊程序集下的服務類 5 /// </summary> 6 /// <param name="services"></param> 7 public static IServiceCollection AddBatchServices(this IServiceCollection services) 8 { 9 //根據指定程序集名稱獲取待注冊服務 10 var batchServices = GetConfigureClass("WebApiApplication"); 11 foreach (var type in batchServices) 12 { 13 type.Value.ToList().ForEach(i => 14 { 15 //注冊服務類 16 services.AddScoped(i, type.Key); 17 }); 18 } 19 return services; 20 } 21 22 /// <summary> 23 /// 根據程序集名稱獲取自定義服務 24 /// </summary> 25 /// <param name="assembly"></param> 26 /// <returns></returns> 27 public static Dictionary<Type, Type[]> GetConfigureClass(string assembly) 28 { 29 Dictionary<Type, Type[]> dic = new Dictionary<Type, Type[]>(); 30 if (!string.IsNullOrEmpty(assembly)) 31 { 32 //獲取程序集對應的類型 33 Assembly dll = Assembly.LoadFrom(assembly); 34 List<Type> lstType = dll.GetTypes().ToList(); 35 lstType.ForEach(x => 36 { 37 //篩選滿足條件的服務類 38 if (x.IsClass && x.GetInterfaces().Length > 0) 39 { 40 dic.Add(x, x.GetInterfaces()); 41 } 42 }); 43 } 44 return dic; 45 } 46 }
然后我們ConfigureServices方法中注冊:
public void ConfigureServices(IServiceCollection services) { //批量注冊 services.AddBatchServices(); }
對於批量注冊,ASP.Net Core允許我們更換默認的IOC容器,感興趣的同學可以試試AutoFac容器支持的程序集掃描式注冊。
注冊我們自己的服務,往往在項目開發過程中是必要的,希望以上簡單的分享能給需要的小伙伴們帶來一點收貨。