2016-11-21 51 views
1

我需要創建一個記錄器,該記錄器應該有一個範圍(類似於TransactionScope類)。實現記錄器範圍而不發送依賴關係

這裏是一個草圖:

public class Logger 
{ 
    private static Logger instance; 

    public void BeginScope(string scopeName) 
    { 
     //... 
    } 

    public static Logger Instance() 
    { 
     // Singleton code 
     return instance; 
    } 

    public void Log(string message) 
    { 
     Console.Writeline(string.Concat(scopeName, message)); 
    } 

    public void EndScope() 
    { 
     //... 
    } 
} 

如何創建記錄範圍,使我開始的範圍後,如果我創造了許多類和使用存在的單記錄,它會使用相同的範圍內,但不發送依賴關係?我在登錄類時不能將範圍用作依賴項。

並且如果我的代碼:

for(var i = 0;i>2000;i++) 
{ 
    Logger.BeginScope("scope_" + i); 
    //create classes that contain methods that logs data 
    Logger.EndScope(); 
} 

應該建立在每個循環的作用域。

+0

你知道[NLOG(http://nlog-project.org/)?他們已經實現了您可能從伐木所需的所有東西,甚至是那些您目前可能尚未意識到的功能。 – Dialecticus

+0

我需要創建範圍和記錄器的概念證明只是一個例子... –

+0

說了這麼多,我不明白你的問題。試圖弄清楚NLog是否可以做你想做的事,但不知道那是什麼。 – Dialecticus

回答

0

這裏是一個草圖:

public class Logger { 
    // use thread local variable - will have separate instance per thread 
    private static readonly ThreadLocal<Logger> _instance = new ThreadLocal<Logger>(() => new Logger()); 
    // scopes stack 
    private readonly Stack<string> _scopes = new Stack<string>(); 

    public static void BeginScope(string scopeName) { 
     // push new scope to the stack 
     _instance.Value._scopes.Push(scopeName); 
    } 

    public static void Log(string message) { 
     // use scope from the top of the stack (first check if not null) 
     Console.WriteLine(string.Concat(_instance.Value._scopes.Peek(), message)); 
    } 

    public static void EndScope() { 
     // remove scope from the top 
     _instance.Value._scopes.Pop(); 
    } 
} 

測試:

for (var i = 0; i < 10; i++) 
{ 
    Logger.BeginScope("scope_" + i);    
    Logger.Log("test"); 
    Logger.BeginScope("inner scope_" + i); 
    Logger.Log("test");     
    Logger.EndScope(); 
    Logger.Log("test"); // back to scope_i 
    Logger.EndScope(); 
} 
+0

如果我開始一個範圍,從另一個類/方法開始另一個範圍,然後關閉第一個範圍,這將不起作用。但這是個好主意...... –

+0

那是怎麼回事?如果你開始第一個範圍,然後第二個 - 你只能關閉第二個,而不是第一個。否則,它不是「範圍」。 – Evk

+0

想象一下在web api中的這個實現,我有兩個控制器。我可以根據每個控制器執行多少時間來關閉作用域 –

0

考慮到所有的日誌記錄也會通過Logger.Instance()(即沒有人可以節省供以後使用的實例),只是在BeginScope替換該實例:

public void BeginScope(string scopeName) 
{ 
    _savedInstance = _instance; 
    _instance = new LoggerForScope(scopeName); 
} 

public void EndScope() 
{ 
    _instance = _savedInstance; 
} 

但是,這是可怕的醜陋,而將失敗範圍交疊。

編輯:

這個怎麼樣?使用範圍進行記錄。但是,你必須記錄器傳遞給想要登錄的方法...

for(var i = 0;i<2000;i++) 
{ 
    using (var scopedLogger = Logger.BeginScope("scope_" + i)) 
    { 
     // use the scoped logger here 
    } 
} 

你不能兼得,我猜,無處不在的靜態實例和一個單獨的範圍。

+0

如果我必須在同一時間從不同的地方登錄 –

+0

當然,但是靜態單例首先不會工作,並且你的問題不僅僅是範圍。 – Haukinger