2013-03-18 45 views
1

我在各種項目中發現的一個非常常見的日誌記錄目標是任何創建日誌條目的類/對象都將自己的類/對象名稱記錄到該條目中。如果日誌條目是針對異常和堆棧跟蹤的,則該信息是免費包含的。但是,如果該日誌條目不是異常,則各種其他方法通常用於得到這樣的結果:反映注入的目標

  1. 硬編碼常量字段到每個類,其保持類的名稱(或記錄器本身!)。日誌記錄器在登錄時被賦予該const。
  2. 記錄器包含反映調用堆棧的代碼,以確定哪個類已作出日誌記錄調用。該名稱然後被添加到日誌條目。
  3. 每個類都被注入一個記錄器實例,該實例已經知道它被注入的類的名稱。

的#3一個簡單的例子是這樣的:

ILogger logger = new MyLogger("AmazingClass"); 
IAmazingClass foo = new AmazingClass(logger); 

我想知道的是,如果任何IOC容器,特別是團結,是能夠幫助解決這個「場景#3」優雅?如果是,如何?

我覺得答案應該很簡單:IOC容器「知道」它將要構建和注入哪個類,並在解析類型之前向「dependee」提供「依賴者」信息。

例如,也許統一可以通過delegate registration和「反向反射」登記這樣實現這一點:

var container = new UnityContainer(); 
container.RegisterType<ILogger, MyLogger>(new InjectionFactory(
    (Type targetOfInjection) => new MyLogger(targetOfInjection.Name) 
); 

予由該語法,但它完全是可信的。也就是說,Unity(或其他國際奧委會容器)爲實際提供的能力提供了什麼?

p.s.我個人對於我的記錄器和日誌記錄「沒問題」,不會爲非例外條目捕獲類/對象名稱。保持代碼更簡單。但是如果我被迫採用這種方法,我通常會採用堆棧反射選項(場景#2)。當他們也被要求捕獲非異常日誌記錄語句中的類名時,知道還有哪些其他方法會讓人感興趣。然而,最終,這個問題集中在使用IOC容器。

回答

1

也就是說,Unity(或其他國際奧委會容器)爲建議的能力提供 ?

我不能回答團結的問題,但使用Simple Injector,您可以按如下所示註冊此:

container.RegisterWithContext<ILogger>(context => 
    new MyLogger(context.ImplementationType.Name)); 

您需要從該Advanced Scenarios section添加使用該code snippetRegisterWithContext擴展方法簡單的注射器文件。更重要的是,即使使用Simple Injector,這種基於上下文的註冊也可以快速解決。

但請注意,基於上下文的注入通常是一種設計氣味。事實上,你在該領域的任何地方都能看到這種模式,但這並不是正確的。所以在你繼續之前,請確保you're not logging too much and your application design follows the SOLID principles