為什麼使用依賴注入和控制反轉
阿新 • • 發佈:2020-12-29
控制反轉(Inversion of Control,縮寫為IoC),是面向物件程式設計中的一種設計原則,可以用來減低計算機程式碼之間的耦合度。
依賴注入(Dependency Injection,簡稱DI)則是一種實現控制反轉的方法。
理解了依賴注入,就理解了控制反轉
依賴注入
依賴項是指一個物件所依賴的物件。
public class IndexController : Controller { private readonly Dependency _dependency = new Dependency(); public IActionResult Index() { _dependency.WriteMessage("message"); return null; } } public class Dependency { public void WriteMessage(string message) { Console.WriteLine(message); } }
在以上程式碼中,在類IndexController
中直接例項化了Dependency
物件,並呼叫其WriteMessage
方法。
那麼Dependency
就是IndexController
的依賴項。這樣的直接依賴會產生問題,應避免使用,原因如下:
- 要用不同的實現替換
Dependency
,必須修改IndexController
類。 - 如果
Dependency
具有依賴項,則必須由IndexController
類對其進行配置。 在具有多個依賴於Dependency
的類的大型專案中,配置程式碼將分散在整個應用中。 - 這種實現很難進行單元測試。 應用需使用模擬
Dependency
類,而這種方法很難實現。
依賴注入通過以下方式解決這些問題:
- 使用介面或基類將依賴關係抽象化。
- 在服務容器中註冊依賴關係。 ASP.NET Core 提供了一個內建的服務容器 IServiceProvider。 服務通常已在應用的
Startup.ConfigureServices
方法中註冊。 - 將服務注入到使用它的類的建構函式中。 服務容器負責建立依賴關係的例項,並在不再需要時將其釋放。
把Dependency
類抽象成介面IDependency
public interface IDependency
{
void WriteMessage(string message);
}
類Dependency
IDependency
public class Dependency : IDependency
{
public void WriteMessage(string message)
{
Console.WriteLine(message);
}
}
通過Startup
類的ConfigureServices
方法,在服務容器中註冊具體型別 為Dependency
的 IMyDependency
服務。AddScoped
表示使用範圍內生命週期註冊服務。
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IDependency, Dependency>();
services.AddControllersWithViews();
}
在IndexController
中注入IDependency
服務並呼叫WriteMessage
方法
public class IndexController : Controller
{
private readonly IDependency _dependency;
public IndexController(IDependency dependency)
{
this._dependency = dependency;
}
public IActionResult Index()
{
_dependency.WriteMessage("message");
return null;
}
}
通過使用依賴注入模式,類IndexController
:
- 不再使用具體型別
Dependency
,僅使用它實現的IDependency
介面。 這樣可以輕鬆地更改IDependency
的實現,而無需修改類IndexController
。 - 不直接建立
Dependency
的例項,而是由服務容器建立。
控制反轉
那麼到底什麼被反轉了?獲得依賴物件的過程被反轉了。
在以上的例子中,IndexController
獲得Dependency
物件的過程被反轉了。以往是IndexController
直接例項化Dependency
物件,現在是由服務容器例項化,並通過IndexController
的建構函式注入。
ASP.NET Core依賴注入
在我之前的文章中有詳細介紹