2009-08-21 61 views
4

日誌框架是否應該注入需要它們的類中,或者每個需要它的類都應該知道該框架並直接使用它?我正在使用Log4Net,目前我正在注入一項服務,將該框架封裝到需要能夠記錄的類中,瞭解日誌記錄可能不會改變,並且大多數部分都需要它,從這種意義上注入答案?將日誌框架注入類

回答

3

注入是從長遠來看更靈活,因爲你可以很容易地有選擇地注入到某些地方,並有選擇地禁用日誌記錄等

2

我認爲沒有什麼錯注射它。他們建議僅僅爲了性能的原因使用靜態變量,但是我看到這與啓動時注入記錄器的區別很小。

1

如果內存性能不是很大的問題,你可以考慮AOP,例如,使用PostSharp。這樣,你的課程根本不需要知道記錄器。您基本上將IL代碼直接注入您的程序集中作爲後構建步驟。 PostSharp使用屬性來標記方法,類甚至整個程序集。甚至有一個plugin使用log4net記錄關心。

編輯: 我提到過內存,因爲每個屬性都爲每個連接點創建一個新的對象。

+0

+1對於PostSharp而言,那個狗屎是神奇的 – 2009-08-21 19:10:22

1

即使你說日誌記錄不會改變,我建議從特定的日誌記錄框架中抽象出來。然而,在所有情況下都不需要注入記錄器實例。

CommonLogging爲例(請參閱this Stackoverflow answer以獲取Common.Logging的簡短描述)例如:您的班級直接與工廠(LoggerManager)對話,但您並未綁定到特定的記錄器實施。

0

如果你在談論依賴注入(比如Spring.NET意義上的說法),那麼它並不重要 - 儘管你從記錄器實例的多個副本中得不到太多的價值。通常情況下,具有特定類/名稱的框架返回的每個記錄器實例無論如何都將是單例,因此問題是您是否想要使用記錄器引用混淆每個實例,而不是每個類的單個靜態引用。如果您擔心更改記錄器實現,請登錄到一個界面(CommonLogging,在另一個答案中提到,執行此操作,並支持log4net和Enterprise Library實現)。

如果你正在談論使用AOP進行注射,那麼我不確定超出某一點,AOP注射更加靈活。您幾乎侷限於使用方法級粒度記錄進入,退出和異常。即使您使用AOP選擇性地注入代碼的某些部分,AOP注入也更像是分散式方法。雖然日誌被吹捧爲AOP理想的交叉問題,但我從來沒有發現基於AOP的日誌記錄在實踐中非常有用(當然,YMMV)。

0

CSharpAtl

我很好奇,究竟你是如何注入log4net的?查看我的問題/社區wiki here

我還看到了您對DI/Log4net問題here的回答。

大多數日誌注入的例子,我已經看到顯示有一個「記錄」一類的注入,這樣的事情:

public class Foo 
{ 
    private ILogger logger; 

    public Foo(ILogger logger) //Injection via constructor 
    { 
    //Which "named" logger is this anyway? Is it Foo's? If so, how is it Foo's? 
    this.logger = logger; 
    } 

    public DoSomeWork(int xyz) 
    { 
    logger.Info("xyz = {0}", xyz); 
    } 
} 

的東西,如log4net的(和NLOG,或者其他人),您通常會創建一個記錄是這樣的:

public class Foo 
{ 
    private static ILogger logger = 
      LogManager.GetLogger(
       System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

    public Foo() 
    { 
    } 

    public DoSomeWork(int xyz) 
    { 
    logger.Info("xyz = {0}", xyz); 
    } 
} 

那麼,如何我的課,富,得到正確的記錄,如果我的依賴注入?另外,也許我不會嚴格按照課程來命名我的記錄器。相反,我可能會根據功能區域(如「DatabaseAccess」,「AppStartup」,「AppShutdown」等)對它們進行命名,這些功能區域可能不是從類型派生的。

您是在注入一個「Logger」(對應於指定的記錄器)還是「LogManager」(對應於Log4net的LogManager),還是在執行其他操作?您是否使用DI平臺的配置功能將注入依賴關係的「命名實例」關聯起來?我認爲Unity支持這樣的事情,儘管我並不確定。

這裏是我會想象注入「日誌管理」將工作:

public class Foo 
{ 
    private static ILogger logger; 

    public Foo(ILogManager logManager) //Injection via constructor 
    { 
    logger = logManager.GetLogger 
        (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

    //Since logger is (should it be?) static, maybe should be like this: 

    if (logger = null) 
    { 
     logManager.GetLogger 
       (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 
    } 
    } 

    public DoSomeWork(int xyz) 
    { 
    logger.Info("xyz = {0}", xyz); 
    } 
} 

這在我看來,注射類似ILogManager(其中將包裹的log4net的日誌管理實施)會比injectng ILogger容易,因爲DI平臺如何知道注入哪個ILogger。

我是DI和.NET日誌記錄平臺的新手(實際上,對於C#和.NET來說,這些都很新穎)。絕大多數我的經驗,在過去的很多年是VB6 + VC++ 6.0

感謝任何信息...

開始編輯...

我已經在SO看了看周圍的一些更多發現你也問過關於AutoFac的問題,所以我猜測你正在使用這個爲你的DI。如果這是真的,那麼我想你也在做類似this或者顯然更好,就像this來解決你的記錄器(按類的類型)。我想這回答了至少在AutoFac中如何注入命名記錄器(例如從Log4Net或NLog)的問題。

End edit ...