2014-02-05 25 views
1

我在一個解決方案中有一個靜態日誌記錄對象在項目之間共享庫中。這是它的結構:管理WCF中的靜態數據

public class AppLog 
{ 
    private static string _logFile; 
    private static string _appName; 

    public static string AppName 
    { 
    get { return _appName; } 
    set 
    { 
     _appName = value; 
     InitLogFilePath(); // initializes _logFile according to _appName 
    } 
    } 

    public static Write(string msg) 
    { 
    // writes to _logFile 
    } 
} 

它工作正常了各種的Windows應用程序和Windows服務:他們可以在啓動時初始化AppLog.AppName和AppLog.Write可以在整個代碼調用。共享模塊寫入根據AppName的初始化命名的文件。

我的問題是WCF Web服務中使用此。 Web服務配置爲InstanceContextMode.PerCallAppLog.AppName正根據ServiceHostBase.Description.Name進行初始化。但由於多個Web服務在相同的AppDomain中運行,因此這些靜態數據是共享的。所以一個ws打電話AppLog.AppName,它被改變的下一個電話,它可能有不同的ServiceHostBase.Description.Name

這又如何重構,因此AppLog.Write仍然可以在整個項目中我的解決方案使用,但不同的處理命名爲每個web服務?

如果能告訴代碼是否是Web服務中運行,如果我能檢索服務的ServiceHostBase.Description,然後我可以保持相應的文件名查找。但我還沒有找到辦法做到這一點。

回答

0

鑑於你記錄的結構還沒有一個很好的解決方式。讓您創建記錄器的實例,通過實例的任何應用程序特定數據(如AppName的),然後該實例存儲在一個私有靜態成員

大多數日誌庫結構。靜態存儲位於應用程序中,而不是日誌記錄庫。這樣可以避免您擁有的共享衝突,並且只會創建一個固定數量的記錄器實例。

爲了說明這一點,這裏是從CodeProject log4net tutorial標準log4net例子。此代碼將當前類名傳遞給記錄器的實例。

private static readonly log4net.ILog log = log4net.LogManager.GetLogger 
    (System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

我的建議是看看更改爲log4net或任何其他在NuGet上可用的日誌包。

0

鑑於你的情況,AppName不是應該在哪裏。您需要一個每個Web服務日誌外觀來保存AppName,並將核心「寫入」邏輯傳遞給您當前的AppLog。然後,每個Web服務都有自己的LogFacade實例。

class LogFacade 
{ 
    public string AppName {get; private set;} 

    LogFacade(string appName) 
    { 
    AppName = appName; 
    } 

    public void Write(string msg) 
    { 
    AppLog.Write(string.format("[{0}]{1}", AppName, msg)); 
    } 
} 

或者正如ErnieL所說,看看log4net。

+0

關於log4net:我現在無法引入新的庫/依賴項。看看你給出的示例代碼,我不認爲這可以工作:AppName需要一個實例,而Write是一個靜態方法。 – jltrem

+0

@jltrem,是的,你是對的。我只是複製你的AppLog。 Write和AppName在實例或靜態方面應該是一致的。 –

+0

好的,所以我的問題仍然存在:從不同的程序集調用此函數時,我如何確定LogFacade的正確實例?如果我可以確定我是否正在Web服務中運行,並且如果是的話,哪些WS正在調用它,那麼我可以識別記錄器實例。 – jltrem