Agenda
前言
IOC
依賴反轉是oop
重要程式設計思想。
Ioc—Inversion of Control
控制反轉
控制反轉是一個設計思想 ,把對於某個物件的控制權移轉給第三方容器.
詳細資訊可以查看小弟另一篇文章 IOC(控制反轉),DI(依賴注入) 深入淺出~~
有沒有人會很好奇說為什麼只需要透過
DependencyResolver.SetResolver
方法我就可以直接使用AutoFac
或其他IOC容器?
1 | //.... |
今天跟大家分享Asp.net MVC
利用什麼設計技巧,讓外部IOC
容器可以很方便融入系統中.
我有做一個可以針對於Asp.net MVC Debugger的專案,只要下中斷點就可輕易進入Asp.net MVC原始碼.
IOC介紹
控制反轉是一個設計思想,把對於某個物件建立,生命週期控制權移轉給第三方統一管理
在設計模組時建議依賴抽象,因為各個模組間不需要知道對方太多細節(實作),知道越多耦合越強。
A
物件內部有使用到B
物件 A
,B
物件中有依賴的成份
控制反轉是把原本A
對B
控制權移交給第三方容器。
降低A
對B
物件的耦合性,讓雙方都倚賴第三方容器。
上面說明太抽象嗎? 可以看一下下面這張圖.
最後對於使用者來說,我只需要認識這個第三方容器並跟這個容器取得我要A物件,至於A物件和其他物件關係使用者不用瞭解
IOC容器框架有很多種但基本上都有下面兩個功能
- 掌控物件生命週期
- 設定物件關係的註冊表(取用時會依照此註冊關係建立物件並自動注入相依物件)
程式碼介紹IOC by Autofac
我們依照此圖做一個簡單範例by Autofac
A
物件會直接引用於B
和C
物件這導致A
掌控B
和C
物件創建和銷毀
如下面程式碼,A物件需要掌控B
和C
生命週期和物件建立.
1 | public class A{ |
如果透過IOC
容器我們就不用擔心物件如何建立和他所依賴B
和C
物件,因為我們會在容器註表中指定他的關係,使用時只需要關注如何使用此物件.
1 | public class A{ |
這個程式碼是利用Autofac
框架,比起上面多了一段註冊程式碼.主要告訴容器物件之間關係和如何掌控物件生命週期.
上面例子最後只需要利用container.Resolve<T>
方法就可以跟容器來取想要的物件,至於引用的物件是如何注入或關係我們就不必關心.
AutoFac IOC容器 和 Asp.net mvc關係
如果Asp.net
沒有搭配IOC容器(預設使用DefaultResolver
)Asp.net MVC
對於使用物件必須寫死在Controller
類別中
無法使用建構子或屬性來決定使用哪個物件
如下面程式碼
1 | public class HomeController : Controller |
如果在建構子使用參數會丟錯誤,在[Day11] Asp.net MVC Controller是怎麼被建立談到建立
Controller
物件透過DefaultControllerActivator
預設使用反射建立Controller
物件呼叫無參數的建構子方法.
因為
Asp.net MVC
建立Controller
是透過Activator.CreateInstance
方法,
如果我們想在建構子傳入參數或是想要統一管理注入的物件,就可以使用IOC
容器來幫我完成
為什麼
Asp.net MVC
使用DependencyResolver.SetResolver
方法替換成IOC
容器就可輕易替換使用容器?
1 | //.... |
DependencyResolver 揭密
DependencyResolver.SetResolver
提供一個替換_current
欄位的機制
1 | /// <summary> |
Asp.net MVC
提供一個介面 IDependencyResolver
讓第三方容器實現並擴充.IDependencyResolver
介面有兩個方法
GetService
返回一個物件GetServices
返回一個物件集合
主要透過這GetService
方法取得使用Controller
物件
1 | public interface IDependencyResolver |
MVC 裡IDependencyResolver
Asp.net MVC
依賴DependencyResolver.Current
來幫我們建立一個Controller
物件
這邊介紹一下在MVC
中三個IDependencyResolver
解析器
CacheDependencyResolver
快取解析器(利用ConcurrentDictionary
是一個多執行緒安全的字典)DefaultDependencyResolver
預設使用解析器(利用反射建立物件)DelegateBasedDependencyResolver
委派解析器.
1 | prprivate sealed class CacheDependencyResolver : IDependencyResolver |
建立Controller
預設使用DefaultDependencyResolver
這個解析器
第三方IOC
容器利用DependencyResolver.SetResolver
方法把DefaultDependencyResolver
替換掉使用他們自己實現的解析器提供物件
不是透過DefaultDependencyResolver
反射來建立物件喔~
小結:
我們了解為什麼Asp.net MVC
可透過DependencyResolver.SetResolver
替換成IOC
容器注入控制器物件.
如果要建立客製化的解析器可以實現IDependencyResolver
介面並使用DependencyResolver.SetResolver
替換DefaultDependencyResolver
預設解析器
DependencyResolver
,Controller
和ControllerFactory
的關係如下圖
下篇會介紹DependencyResolver
在Asp.net MVC
中有哪些實際的應用.
此文作者:Daniel Shih(石頭)
此文地址: https://isdaniel.github.io/ithelp-day13/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!