.NET Core第12天_服務依賴注入_IoC容器生命週期_ConfigureServices
我們前面有示範幾種
服務注入
比方
注入MVC服務
services.AddMvc();
注入EF資料庫服務
services.AddDbContext<NorthwindContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("DbConnectonString")));
注入驗證服務
services.AddAuthentication();
全寫在Startup.cs的
public void ConfigureServices(IServiceCollection services)方法當中
關於依賴注入部分可以參考之前篇章
何謂IoC Container
Inversion of Control 控制反轉
把對於某個物件的控制權移轉給第三方容器,藉此原本兩物件互相依賴變更為
兩物件都依賴於第三方物件(俗稱容器)
在.net core內建的Container Service就是IServiceCollection這個型別
用於註冊服務到.net core容器中,預設支援constructor injection。
那事實上還有其餘很多方法
生命週期:
Transient:每次被請求都會創建新的實體
Transient objects are always different; a new instance is provided to every controller and every service.
Scoped:每次Web請求會創建一個新實體,直到web請求結束就銷毀。
Scoped objects are the same within a request, but different across different requests.
Singleton:一旦被創建實體就會持續一直用,直到應用停止才銷毀。
Singleton objects are the same for every object and every request.
ServiceType Class | In the capacityof same HttpRequest | Different Http Request |
AddSingleton | The same Instance of repository served | The same Instance of repository served |
AddScoped | Same Instance | Different Instance |
AddTransient | Every time New Instance | Every time New Instance |
新增一個.net core Model-View-Controller專案
並添加一個新的控制器取名為ProductController
add new folder 命名為Database
並新增interface命名為 IProductService,定義要實作的兩個method 規格
分別是getInstanceId()跟getProductName()。
另外新增額外實作該介面的具體Class ProductService
IProductService.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 | using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ContainerServiceMethods.Database { public interface IProductService { string getInstanceId(); string getProductName(int id); } } |
ProductService.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ContainerServiceMethods.Database { public class ProductService : IProductService { string InstanceId { get; set; } public ProductService() { InstanceId = Guid.NewGuid().ToString(); } public string getInstanceId() { return InstanceId; } public string getProductName(int id) { return "愛之味-牛奶花生"; } } } |
在這我們為了驗證物件是否為舊的還是新創建出來的因此透過
於建構子設定唯一的Guid來識別。
在ProductService中調整action method跟相應建構子傳入部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | using ContainerServiceMethods.Database; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace ContainerServiceMethods.Controllers { public class ProductController : Controller { IProductService _p1; IProductService _p2; public ProductController(IProductService p1, IProductService p2) { _p1 = p1; _p2 = p2; } public string[] GetInstances() { string[] data = new string[2]; data[0] = _p1.getInstanceId(); data[1] = _p2.getInstanceId(); return data; } } } |
於Startup.cs
public void ConfigureServices(IServiceCollection services)方法
我們去注入剛創建好的自訂的服務
使用services.AddSingleton<IProductService, ProductService>();
第一個參數傳入interface第二個則是實作該interface的class
這裡可以看到使用Singleton效果物件ID都一樣
5071849d-8884-4ffb-94af-fd095a93985c
而且不管在重整呼叫同一個action method路由,物件id都不會變。
回到Startup.cs修改成
使用services.AddScoped<IProductService, ProductService>();
Scoped是每次Web請求會創建一個新實體,直到web請求結束就銷毀。
所以我們要模擬再次跳轉到這一個網址路由
我們可以到Views/Shared/_Layout.cshtml中調整多擴充一個訪問按鈕
來方便我們直接訪問就不用透過輸入網址方式
那就能發現當重整或是重呼叫一次同樣的url時候會有不同的object id
回到Startup.cs修改成
改使用 services.AddTransient<IProductService, ProductService>();
可以從第一次呼叫就發現回傳回來的兩個object id都不同
第二次也都是跟第一次完全不同的id
原因在於Transient
每次要求元件時就建立一個新的,永不共用。
Ref:
What is the AddSingleton vs AddScoped vs Add Transient C# Asp.net Core?
https://www.tutorialspoint.com/what-is-the-addsingleton-vs-addscoped-vs-add-transient-chash-asp-net-core
Understanding AddTransient Vs AddScoped Vs AddSingleton In ASP.NET Core
https://www.c-sharpcorner.com/article/understanding-addtransient-vs-addscoped-vs-addsingleton-in-asp-net-core/
AddTransient, AddScoped and AddSingleton Services Differences
https://stackoverflow.com/questions/38138100/addtransient-addscoped-and-addsingleton-services-differences
IOC(控制反轉) , DI(依賴注入) 深入淺出~~
https://dotblogs.com.tw/daniel/2018/01/17/140435
筆記 - 不可不知的 ASP.NET Core 依賴注入
https://blog.darkthread.net/blog/aspnet-core-di-notes/
Check also
回覆刪除https://qawithexperts.com/article/asp-net/difference-between-addtransient-addscoped-and-addsingleton-i/404