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

Unity 1.2 依賴注入實戰(一):從基本註冊到注入鏈探索

     編輯:關於.NET

Unity 是 Microsoft Patterns & Practices 推出的輕量級依賴注入容器。本文記錄初探 Unity 1.2 的學習歷程,從基本型別註冊開始,逐步探討多重註冊、具名解析與 ResolveAll 行為差異。

第一個 Demo:基本註冊與解析

public interface ILogService { void Write(string message); }

public class CnsLogService : ILogService {
    public void Write(string message) => Console.WriteLine($"Cns-exception msg:{message}");
}

// 使用 Unity
var container = new UnityContainer();
container.RegisterType<ILogService, CnsLogService>();

var service = container.Resolve<ILogService>();
service.Write("oh,exception occured!");
// 輸出:Cns-exception msg:oh,exception occured!

注入鏈實驗:多重註冊同一介面

嘗試連續註冊兩個實作:

public class DataLogService : ILogService {
    public void Write(string message) => DailyPractice.Utility.Log.AddLog(message);
}

namespace DailyPractice.Utility {
    public class Log {
        public static void AddLog(string message) => Console.WriteLine($"Data-exception msg:{message}");
    }
}

// 連續註冊
container.RegisterType<ILogService, CnsLogService>()
         .RegisterType<ILogService, DataLogService>();

var service = container.Resolve<ILogService>();
service.Write("oh,exception occured!");
// 輸出:Data-exception msg:oh,exception occured!

觀察:後註冊的 DataLogService 覆蓋先前註冊,CnsLogService 未被執行。

ResolveAll 嘗試

var services = container.ResolveAll<ILogService>();
foreach (var svc in services) {
    svc.Write("haha, you have an exception 了吧!");
}
// 輸出:無任何輸出!

困惑:ResolveAll 回傳空集合?

關鍵發現:具名註冊才能被 ResolveAll 解析

參考 TerryLee 部落格,必須在註冊時指定名稱:

container.RegisterType<ILogService, CnsLogService>("CnsLogService")
         .RegisterType<ILogService, DataLogService>("DataLogService");

var services = container.ResolveAll<ILogService>();
foreach (var svc in services) {
    svc.Write("haha, you have an exception 了吧!");
}
// 輸出:兩個實作皆執行

原理分析

Unity 容器中,ResolveAll 僅能解析具名註冊的型別對應。未指定名稱的註冊視為預設對應,僅能透過 Resolve<T>() 取得單一實例(最後註冊者勝出)。

總結與心得

  • RegisterType<TFrom, TTo>():預設對應,後者覆蓋前者
  • RegisterType<TFrom, TTo>("name"):具名對應,可共存
  • Resolve<T>():取得預設對應(單一實例)
  • ResolveAll<T>():取得所有具名對應實例集合
  • 實務上,單一介面多實作場景(如多種日誌輸出、多種付款管道)應善用具名註冊 + ResolveAll

下一篇將探討 XML 組態檔配置與進階生命週期管理。

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