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

Unity 屬性注入全解析:從基礎用法到命名映射的進階實戰

     編輯:關於.NET

Property/Setter Injection 適用場景

  • 可選依賴,對象可在無依賴情況下工作
  • 依賴需在運行時動態變更或外部可見
  • 構造函數參數過多導致「望遠鏡式構造」反模式
  • 希望調用方直觀看到可注入依賴(屬性比構造函數參數更易發現)

基礎用法:[Dependency] 標記自動裝配

public abstract class Player {
    [Dependency] // 標記需容器注入
    public Song Song { get; set; }
    public abstract string Name { get; }
    public void Play() => Console.WriteLine($"{Name}: Now Playing [{Song.Name}] by ({Song.Singer})");
}
public class Song {
    public string Name => "My Love";
    public string Singer => "Westlife";
}
public class Mp3Player : Player { public override string Name => "Mp3 Player"; }
public class CDPlayer : Player { public override string Name => "CD Player"; }

容器解析驗證

var container = new UnityContainer();
container.RegisterType<Player, Mp3Player>(); // Song 為具體類,無需註冊自動創建
var player = container.Resolve<Player>();
player.Play(); // 輸出: Mp3 Player: Now Playing [My Love] by (Westlife)
屬性注入基礎輸出
圖 1:屬性注入自動解析 Song 依賴

進階:命名映射控制具體注入類型

當接口有多個實現(如 Player 對應 Mp3Player/CDPlayer)時,屬性注入需指明期望哪個具體類。

PlayerStore 場景:指定最受歡迎播放器

public class PlayerStore {
    [Dependency("Mp3Player")] // 指定命名映射
    public Player PopularPlayer { get; set; }
}

容器註冊與解析

var container = new UnityContainer();
container.RegisterType<Player, Mp3Player>("Mp3Player"); // 註冊命名映射
container.RegisterType<Player, CDPlayer>("CDPlayer");
var store = container.Resolve<PlayerStore>();
Console.WriteLine(store.PopularPlayer.Name); // 輸出: Mp3 Player
命名映射輸出
圖 2:命名映射精確控制注入目標

BuildUp 支持現有實例屬性注入

同方法注入,Resolve 獲取現有實例不觸發屬性注入,需調用 container.BuildUp<T>(existing) 強制執行。

循環引用風險與規避

雙向屬性依賴(A.PropB → B.PropA → A.PropB)將導致解析時無限遞歸。參考《Unity 循環引用四大場景》第 4 類模式,設計時嚴禁雙向屬性依賴。

最佳實踐建議

  1. 僅標記真正需要的依賴,避免過度注入增加圖複雜度
  2. 屬性設置器保持 public,容器需訪問 setter
  3. 命名映射配合接口隔離,而非直接依賴具體類
  4. 文檔化注入契約:XML 註釋說明屬性用途、是否必填、預期實現
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved