本篇的話介紹下IOC和ID的含義以及如何使用.Net Core中的DI。
一。我是這么理解IOC和DI的:
IOC:沒有用IOC之前是直接new實例來賦值,使用IOC之后是通過在運行的時候根據配置來實例化具體對象,這個控制權由內部轉到外部的過程就可以理解為IOC(控制反轉)
DI:由IoC容器在運行期間,動態地將某種依賴關系注入到對象之中
二。在.Net Core中使用
假設有這樣一個業務:現在網站記錄日志是存在文本文件中,可能以后會需要存在數據庫,這時候就不能直接new來實例化具體對象,可以用DI來解決。
1.我們先建好一個.Net Core項目,在其中添加一個接口和兩個具體實現類:
public interface ILog { void Write(string msg); }
public class FileLog : ILog { public void Write(string msg) { //假設這里是存入文件 Debug.WriteLine("FileLog:" + msg); } }
public class DBLog : ILog { public void Write(string msg) { //假設這里是存入數據庫 Debug.WriteLine("DBLog:" + msg); } }
2.在Startup的ConfigureServices方法中注冊,假設現在使用文件來記錄日志:
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddSingleton<ILog, FileLog>(); }
public class HomeController : Controller { ILog log = null; public HomeController(ILog _log) { log = _log; } public IActionResult Index() { log.Write("記錄一個錯誤消息"); return View(); } }
現在運行項目的話會輸出 FileLog:記錄一個錯誤消息 ,如果以后需要改成數據庫只需要改成如下:
services.AddSingleton<ILog, DBLog>();
通過這種方式就將具體實現解耦了,以后新增Redis記錄或者其他記錄方式,只需要增加對應的類實現ILog接口再通過配置即可。
如果我們想使用.Net Core中已經通過DI注冊好的類,可以在控制器的構造函數中寫上接口名即可(前提是.Net Core中已經注冊了該接口的具體實現類)
public HomeController(IHostingEnvironment env) { Console.BackgroundColor = ConsoleColor.Red; Console.WriteLine(env.EnvironmentName); }
三。.NET Core DI 為我們提供的實例生命周有三種:
1.Transient: 每一次都會創建一個新的實例
2.Scoped: 在同一個Scope內只初始化一個實例 ,可以理解為( 每一個request級別只創建一個實例,同一個http request會在一個 scope內)
3.Singleton :整個應用程序生命周期以內只創建一個實例
我們可以通過具體業務來選擇不同的實例創建方式。