Unity 通過繼承 LifetimeManager 的具體類型控制實例引用持有方式與銷毀時機。內置兩大管理器覆蓋主流場景:
Resolve 返回同一實例,實現單例模式RegisterInstance 默認採用此管理器定義接口與實現:
public interface IPlayer { void Play(); }
public class Mp3Player : IPlayer {
public void Play() => Console.WriteLine("Playing Mp3");
}
var container = new UnityContainer();
container.RegisterType<IPlayer, Mp3Player>();
var p1 = container.Resolve<IPlayer>();
var p2 = container.Resolve<IPlayer>();
Console.WriteLine($"P1 Hash: {p1.GetHashCode()}, P2 Hash: {p2.GetHashCode()}");
// 輸出不同 HashCode,證實為不同實例
container.RegisterType<IPlayer, Mp3Player>(new ContainerControlledLifetimeManager());
var p1 = container.Resolve<IPlayer>();
var p2 = container.Resolve<IPlayer>();
Console.WriteLine($"P1 Hash: {p1.GetHashCode()}, P2 Hash: {p2.GetHashCode()}");
// 輸出相同 HashCode,確認為同一實例
var container = new UnityContainer();
var mp3 = new Mp3Player();
container.RegisterInstance<IPlayer>(mp3); // 隱式使用 ContainerControlledLifetimeManager
var p1 = container.Resolve<IPlayer>();
var p2 = container.Resolve<IPlayer>();
// 同樣輸出相同 HashCode
| 管理器 | 引用類型 | 適用場景 | 注意事項 |
|---|---|---|---|
| ContainerControlledLifetimeManager | 強引用 | 真正單例、有狀態服務、昂貴資源共享 | 容器銷毀前實例不釋放,注意內存佔用 |
| ExternallyControlledLifetimeManager | 弱引用 | 緩存場景、外部作用域管理、需配合 GC 的對象 | 實例可能意外消失,Resolve 時需檢查 null |
| 無指定(默認) | 無引用 | 無狀態服務、輕量級對象、每次需全新實例 | 高頻調用可能帶來 GC 壓力 |
自定義 LifetimeManager 可實現請求級、會話級、線程級等進階作用域,滿足 Web 應用複雜生命周期需求。