序
致謝
關於本書
- 誰適合閱讀本書
- 如何閱讀本書
- 書寫慣例
- 此區塊會提示當前範例原始碼的所在位置。
- 注意事項。
- 相關資訊。
- 通常是筆者的碎碎念、個人觀點(不見得完全正確或放諸四海皆準),或額外的補充說明。
- 需要準備的工具
- 範例程式與補充資料
- 版本更新紀錄
關於作者
- Part I:基礎篇
第 1 章:導論
- 本章範例原始碼位置:
- 為什麼需要 DI?
- 動態繫結
- 可維護性
- 寬鬆耦合
- 可測試性
- 平行開發
- 什麼是 DI?
- 入門範例—非 DI 版本
- 開放/封閉原則
- 入門範例—DI 版本
- 提煉介面(Extract Interface)
- 控制反轉(IoC)
- 何時該用 DI?
- 本章回顧
第 2 章:DI 用法與模式
- 本章範例原始碼位置:
- 設計模式梗概
- 小引-電器與介面
- Null Object 模式
- Decorator 模式
- Composite 模式
- Adapter 模式
- Factory 模式
- 注入方式
- 建構式注入
- 已知應用例
- 用法
- 範例程式
- 屬性注入
- 已知應用例
- 用法
- 範例程式
- Strategy 模式
- 方法注入
- 已知應用例
- 用法
- 範例
- Ambient Context 模式
- Context 的中文術語
- 已知應用例
- 範例程式(一)
- 範例程式(二)
- Service Locator 模式
- 過猶不及-再談建構式注入
- 半吊子注入
- 阻止相依蔓延
- 解決「半吊子注入」
- 過度注入
- 重構成參數物件
- 多載建構函式
- 重構成 Façade 模式
- 單一責任原則
- 本章回顧
第 3 章:DI 容器
- 本章範例原始碼位置:
- DI 容器簡介
- 物件組合
- 自製 DI 容器
- DI 容器與 Factory 模式
- 自製 DI 容器—2.0 版
- 現成的 DI 容器
- MEF 是 DI 容器嗎?
- 物件組合
- 使用 XML
- 使用程式碼
- 自動註冊
- 自動或手動?隱含或明確?
- 自動匹配
- 深層解析
- 物件生命週期管理
- 記憶體洩漏問題
- 生命週期選項
- 攔截
- AOP 與攔截
- 使用 Decorator 模式實現攔截
- 本章回顧
- Part II:實戰篇
第 4 章:DI 與 ASP.NET MVC 分層架構
- 本章範例原始碼位置:
- 分層架構概述
- 關於洋蔥架構
- Repository 模式
- Repository 參考資料
- MVC 分層架構範例 V1-緊密耦合
- 本節範例的原始碼位置:
- 領域模型
- 資料存取層
- 應用程式層
- 展現層
- 審視目前設計
- MVC 分層架構範例 V2-寬鬆耦合
- 真實案例:為了方便測試而切換資料來源
- 此範例的原始碼位置:
- 領域模型
- 資料存取層
- 應用程式層
- 展現層
- 組合物件
- 切換 Controller 工廠
- 審視目前設計
- 避免過度設計
- YAGNI
- MVC 分層架構範例 V3-簡化一些
- 此範例的原始碼位置:
- 資料存取層
- 應用程式層
- 展現層
- 審視目前設計
- 一個 HTTP 請求搭配一個 DbContext
- 本節範例的原始碼位置:
- ASP.NET MVC 5 的
IDependencyResolver - 實作自訂的
IDependencyResolver元件 - 此範例的原始碼位置:
- ASP.NET MVC 5 應用程式的生命週期
- 本章回顧
第 5 章:DI 與 ASP.NET Web API
- 本章範例原始碼位置:
- ASP.NET Web API 管線
- 訊息處理常式
- Controller 是怎樣建成的?
- Controller 建立完成後
- 注入物件至 Web API Controller
- 抽換 IHttpControllerActivator 服務
- 純手工打造
- 使用 DI 容器:Unity
- 抽換 IDependencyResolver 服務
- IDependencyResolver 與 IDependencyScope
- 純手工 DI 範例
- 步驟 1:實作
IDependencyResolver介面 - 步驟 2:替換預設的型別解析器
- 使用 DI 容器:Unity
- 使用 DI 容器:Autofac
- 本章回顧
第 6 章:更多 DI 實作範例
- 本章範例的專案原始碼位置:
- 共用程式碼
- DI 與 ASP.NET MVC 5
- 練習:使用 Unity
- Step 1:建立新專案
- Step 2:設定 Unity 容器
- 在一個 HTTP 請求的範圍內共享同一個物件
- Step 3:建立 Controller
- DI 與 ASP.NET Web Forms
- 問題描述
- 解法
- 練習:使用 Unity
- Step 1:建立新專案
- Step 2:註冊型別
- Step 3:撰寫 HTTP Handler
- Step 4:註冊 HTTP Handler
- Step 5:撰寫測試頁面
- 練習:使用 Unity 的 BuildUp 方法
- 練習:使用 Autofac
- Step 1:建立新專案
- Step 2:註冊型別
- Step 3:撰寫 HTTP Handler
- Step 4:註冊 HTTP Handler
- Step 5:撰寫測試頁面
- DI 與 WCF
- 問題描述
- 解法
- 練習:使用 Unity
- Step 1:建立 WCF 服務
- Step 2:撰寫自訂的 ServiceHostFactory
- Step 3:撰寫自訂的 ServiceHost
- Step 4:實作 IContractBehavior 介面
- Step 5:實作 IInstanceProvider 介面
- Step 6:設定 Unity 容器
- Step 7:修改 Web.config
- Step 8:撰寫用戶端程式
- 練習:使用 Autofac.Wcf 套件
- Step 1:建立 WCF 服務
- Step 2:撰寫自訂的 ServiceHostFactory
- Step 3:設定 Autofac 容器
- Step 4:修改 Web.config
- Step 5:撰寫用戶端程式
- 本章回顧
- Part III:工具篇
第 7 章:Unity 學習手冊
- 本章範例原始碼位置:
- Unity 快速入門
- Hello, Unity!
- 註冊型別對應
- 串接呼叫
- 註冊既有物件
- 解析
- 解析一個物件:
Resolve - 具名註冊與解析
- 解析多個物件:
ResolveAll - 註冊與解析泛型
- 檢查註冊
- 使用組態檔來設定容器
- Unity 組態檔基本格式
- 載入組態檔設定
- 執行時期組態 vs. 設計時期組態
- 註冊與解析-進階篇
- 共用的範例程式
- 情境
- 設計
- 程式碼
- 自動註冊
- 解決重複型別對應的問題
AllClasses類別WithMappings類別- 自動匹配
- 自動匹配規則
- 手動匹配
- 循環參考問題
- 注入參數
- 解析物件時改寫注入之參數與物件
- 注入屬性
- 延遲解析
- 使用
Lazy<T> - 使用自動工廠
- 注入自訂工廠
- 物件生命週期管理
- 預設的生命週期
- 指定生命週期
- Transient vs. Per-Resolve
- Per-Request 生命週期
- 階層式容器
- 選擇生命週期管理員
- 攔截
- InterfaceInterceptor 範例
- Step 1:加入 Unity 攔截套件
- Step 2:實作攔截行為
- Step 3:註冊攔截行為
- 本章重點回顧
附錄一:DI 容器實務建議
- 容器設定
- 避免對同一個組件(DLL)重複掃描兩 次或更多次
- 使用不同類別來註冊不同用途的元件
- 使用非靜態類別來建立與設定 DI 容器
- 不要另外建立一個 DLL 專案來集中處理相依關係的解析
- 為個別組件加入一個初始化類別來設定相依關係
- 掃描組件時,盡量避免指定組件名稱
- 生命週期管理
- 優先使用 DI 容器來管理物件的生命週期
- 考慮使用子容器來管理 Per-Request 類型的物件
- 在適當時機呼叫容器的 Dispose 方法
- 元件設計相關建議
- 避免建立深層的巢狀物件
- 考慮使用泛型來封裝抽象概念
- 考慮使用 Adapter 或 Façade 來封裝 3rd-party 元件
- 不要一律為每個元件定義一個介面
- 對於同一層(layer)的元件,可依賴其具象型別
- 動態解析
- 盡量避免把 DI 容器直接當成 Service Locator 來使用
- 考慮使用物件工廠或
Func<T>來處理晚期繫結
附錄二:初探 ASP.NET 5 的內建 DI 容器
- 練習步驟
- 步驟 1:建立專案
- 步驟 2:加入必要組件
- 步驟 3:將 Web API 元件加入 ASP.NET 管線
- 步驟 4:加入 API Controller
- 步驟 5:撰寫測試用的服務類別
- 步驟 6:注入相依物件至 Controller 的建構函式
- 結語
版權頁
- .NET 相依性注入
