介紹
不要依賴於具體的實現,應該依賴於抽象,高層模組不應該依賴於底層模組,二者應該依賴於抽象。簡單的說就是為了更好的解耦。而控制反轉(Ioc)就是這樣的原則的其中一個實現思路, 這個思路的其中一種實現方式就是依賴注入(DI)。ASP.NET Core內建有對依賴注入(DI)的支援,開發者只需要定義好介面後,在Startup.cs的ConfigureServices方法裡使用對應生命週期的繫結方法即可。
只要是用new例項化的都是存在依賴的。
生命週期
AddSingleton→AddTransient→AddScoped
Singleton(單例)
服務在第一次請求時被建立(或者當我們在ConfigureServices中指定建立某一例項並執行方法),其後的每次請求將沿用已建立服務。如果開發者的應用需要單例服務情景,請設計成允許服務容器來對服務生命週期進行操作,而不是手動實現單例設計模式然後由開發者在自定義類中進行操作。
圖片來源自:https://blog.csdn.net/weixin_47498376/article/details/116177389
services.AddSingleton<IApplicationService,ApplicationService>
比如某些公共類等
Scoped(作用域)
一次請求開始到請求結束 ,這次請求中獲取的物件都是同一個
圖片來源自:https://blog.csdn.net/weixin_47498376/article/details/116177389
services.AddScoped<IApplicationService,ApplicationService>
如果該service在一個請求過程中多次被用到,並且可能共享其中的欄位或者屬性,那麼就使用scoped,例如httpcontext (感謝群里老哥的幫助)
Transient(瞬時)
每一次獲取的物件都不是同一個,它最好被用於輕量級無狀態服務(如我們的Repository和ApplicationService服務)
圖片來源自:https://blog.csdn.net/weixin_47498376/article/details/116177389
services.AddTransient<IApplicationService,ApplicationService>
如果該service在一次請求中只使用一次,那麼就註冊Transient就好了。
注入方式
/// <summary>
/// 使用者介面
/// </summary>
public interface IUserService
{
string GetName();
}
/// <summary>
/// 使用者實現
/// </summary>
public class UserService : IUserService
{
public string GetName()
{
return "AZRNG";
}
}
需要在ConfigureServices方法進行注入
建構函式注入
服務作為建構函式引數新增,並且執行時從服務容器中解析服務。
private readonly IUserService _userService;
public UserController(IUserService userService)
{
_userService = userService;
}
[HttpGet]
public ActionResult GetName()
{
return Ok(_userService.GetName());
}
FromServices操作注入
[HttpGet]
public ActionResult GetName([FromServices] IUserService _userService)
{
return Ok(_userService.GetName());
}
核心
在.NET Core中DI的核心分為兩個元件:IServiceCollection和 IServiceProvider。
- IServiceCollection負責註冊
- IServiceProvider負責提供例項
public void ConfigureServices(IServiceCollection services)
{
//將服務生命期的範圍限定為單個請求的生命期
services.AddTransient<IUserService, UserService>();
}
獲取服務
private readonly IUserService _userService;
public HomeController(IUserService userService)
{
_userService = userService;
}
public IActionResult Index()
{
var info = _userService.GetInfo();
return View();
}
IServiceProvider獲取
private readonly IServiceProvider _service;
public UserController(IServiceProvider service)
{
_service = service;
}
[HttpGet]
public ActionResult GetName()
{
var _userService = (IUserService)_service.GetService(typeof(IUserService));
return Ok(_userService.GetName());
}
statrup中獲取服務
var provider = services.BuildServiceProvider();
var userserivce = provider.GetService<IUserService>();
//或
var userservice2 = provider.GetRequiredService<IUserService>();