類僅定義一個構造函數,容器無需任何配置自動解析參數並注入。
public class Mp3Player : IPlayer {
private readonly Song _song;
public Mp3Player(Song song, Owner owner) { // 唯一構造函數
_song = song;
}
public void Play() => Console.WriteLine($"Now Playing [{_song.Name}] by ({_song.Singer})");
}
var container = new UnityContainer();
container.RegisterType<IPlayer, Mp3Player>(); // Song、Owner 為具體類自動創建
var player = container.Resolve<IPlayer>();
player.Play(); // 正常輸出
Unity 提供兩種選擇機制,優先級遞減:
public class Mp3Player : IPlayer {
private readonly Song _song;
[InjectionConstructor] // 明確指定此構造函數用於 DI
public Mp3Player(Owner owner) { } // 僅注入 Owner
public Mp3Player(Song song, Owner owner) { // 完整構造函數,非 DI 入口
_song = song;
}
// ...
}
容器將使用 Mp3Player(Owner) 進行注入,Song 依賴缺失需在其他地方補充。
public class Mp3Player : IPlayer {
private readonly Song _song;
public Mp3Player(Owner owner) { } // 1 參數
public Mp3Player(Song song, Owner owner) { // 2 參數 → 被選中
_song = song;
}
// ...
}
若無 [InjectionConstructor],容器自動選擇參數最多的構造函數。警告:若存在多個「參數最多」構造函數(參數數量相同),容器拋出異常,必須用 Attribute 明確指定。
Resolve 獲取現有對象不執行構造函數注入;BuildUp 也不支持(對象已構造)[Dependency] + BuildUp)「如果你不確信要使用哪種注入方式,建議還是使用 Constructor Injection。它更符合幾乎所有的一般需求。」—— Unity 官方文檔
[InjectionConstructor] 明確意圖