首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Unity 依賴注入實戰:建構函式注入與容器自動組裝

     編輯:關於.NET

場景:手動組裝 vs 容器自動組裝

傳統手動組裝

var dependency = new DependencyObject { Value = "Dependency" };
var logicObj = new LogicObject(dependency); // 顯式構造依賴鏈
Assert.AreSame(logicObj.Dependency, dependency);

Unity 容器自動組裝

IUnityContainer container = new UnityContainer();
container.RegisterInstance(dependency); // 註冊具體實例
container.RegisterType(); // 註冊類型映射 (預設單例)

var logicObj = container.Resolve(); // 容器自動解析注入
Assert.AreSame(logicObj.Dependency, dependency);

核心代碼完整版

using System;
using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace MyTest {
    [TestClass]
    public class UnitTest1 {
        IUnityContainer mContainer;

        [TestInitialize]
        public void MyTestInitialize() {
            mContainer = new UnityContainer();
        }

        class DependencyObject {
            public string Value { get; set; }
        }

        class LogicObject {
            private readonly DependencyObject _dependency;
            public LogicObject(DependencyObject dependency) { // 建構函式注入
                _dependency = dependency;
            }
            public DependencyObject Dependency => _dependency;
        }

        [TestMethod]
        public void TestNormal() { /* 手動組裝 */ }

        [TestMethod]
        public void TestUnityContainer() { /* 容器自動組裝 */ }
    }
}

建構函式注入機制解析

  1. RegisterInstance:向容器登記「此介面/類型由這個具體實例滿足」
  2. RegisterType:登記類型映射,容器會**反射分析建構函式參數**,遞迴解析依賴
  3. Resolve:觸發物件圖建構:
    1. 檢查 LogicObject 建構函式需 DependencyObject
    2. 容器查找 DependencyObject 註冊 → 找到 RegisterInstance 登記的實例
    3. 以該實例呼叫 new LogicObject(dependency)
    4. 返回建構完成的 LogicObject

優勢與爭議

優勢

  • 解耦:LogicObject 不知 DependencyObject 如何建構、從何而來
  • 集中管理:依賴關係在容器註冊處一目瞭然
  • 生命週期控制:單例、PerResolve、PerThread、Hierarchical 等策略
  • 測試友善:單元測試輕鬆替換 Mock/Stub

爭議:依賴關係隱形化

「手動代碼裡依賴關係一目瞭然,Unity 註冊後依賴關係變得隱晦,難以從消費者代碼直接看出。」

回應策略:

  • **註冊代碼即文件**:集中式註冊模組 (如 UnityConfig.RegisterTypes()) 作為架構藍圖
  • **建構函式保持顯式**:參數列表清楚宣告需求,**不使用屬性注入** 繞過編譯器檢查
  • **工具支援**:ReSharper、VS 2022+ 提供 DI 圖譜視覺化
  • **約定優於配置**:container.RegisterTypes(...) 掃描組件自動註冊,減少樣板代碼

進階:ObjectBuilder 底層

Unity 建構於 **ObjectBuilder 2** 之上,提供:建構策略鏈、生命週期管理器、建構計畫緩存、攔截器整合 (AOP)。理解 ObjectBuilder 有助於診斷循環依賴、建構失敗等疑難雜症。

結語

建構函式注入是 DI 最純粹、最安全的形式。Unity 作為輕量級容器,配合 RegisterInstance/RegisterType/Resolve 三步曲,能優雅解決複雜物件圖組裝問題。關鍵在於:**將註冊代碼視為架構文件,建構函式視為契約,容器視為基礎設施**——而非魔法黑盒。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved