回答
實現這種事情的最好方法是使用攔截,有幾種方法可以做到這一點,儘管它們都有些侵入性。一個是從ContextBoundObject派生所有的對象。 Here是使用這種方法的一個例子。另一種方法是使用其中一個現有的AOP庫來實現這一點。像Castle Project這樣的動態代理就是其中的許多核心。這裏有幾個環節: Spring.Net PostSharp Cecil
可能有幾個人,我知道Castle Windsor,並Ninject無論在國際奧委會功能之上提供AOP功能。
一旦AOP就緒後,您只需編寫一個攔截器類,將關於調用方法的信息寫入log4net。
如果其中一個AOP框架能夠爲您提供這種功能,我其實不會感到驚訝。
你可以使用後之類的編譯Postsharp。來自網站的樣本談到設置一個跟蹤器來輸入/退出一個方法,這與你想要的非常相似。
看一看:
How do I intercept a method call in C#? PostSharp - il weaving - thoughts
也是如此搜索「AOP」或「面向方面編程」和PostSharp ......你會得到一些有趣的結果。
我不知道您的實際需求是什麼,但這裏有一個廉租選項。這不正是「自動」,但您可以使用堆棧跟蹤剝離你的方式尋找,不會要求傳遞參數的信息 - 類似ckramer的建議有關攔截:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
namespace TracingSample
{
class Program
{
static void Main(string[] args)
{
DoSomething();
}
static void DoSomething()
{
LogEnter();
Console.WriteLine("Executing DoSomething");
LogExit();
}
static void LogEnter()
{
StackTrace trace = new StackTrace();
if (trace.FrameCount > 1)
{
string ns = trace.GetFrame(1).GetMethod().DeclaringType.Namespace;
string typeName = trace.GetFrame(1).GetMethod().DeclaringType.Name;
Console.WriteLine("Entering {0}.{1}.{2}", ns, typeName, trace.GetFrame(1).GetMethod().Name);
}
}
static void LogExit()
{
StackTrace trace = new StackTrace();
if (trace.FrameCount > 1)
{
string ns = trace.GetFrame(1).GetMethod().DeclaringType.Namespace;
string typeName = trace.GetFrame(1).GetMethod().DeclaringType.Name;
Console.WriteLine("Exiting {0}.{1}.{2}", ns, typeName, trace.GetFrame(1).GetMethod().Name);
}
}
}
}
你可以結合類似與繼承上面的例子中,在基本型採用非虛擬公共成員來表示的操作方法,然後調用虛擬成員實際上做的工作:
public abstract class BaseType
{
public void SomeFunction()
{
LogEnter();
DoSomeFunction();
LogExit();
}
public abstract void DoSomeFunction();
}
public class SubType : BaseType
{
public override void DoSomeFunction()
{
// Implementation of SomeFunction logic here...
}
}
再次 - 沒有太多的「自動「關於這一點,但如果你不需要在每一個方法invoc上進行檢測,那麼它的工作就會受到限制通貨膨脹。
希望這會有所幫助。
的Decorator Pattern可能會有幫助。
您可以使用CodePlex上的開源框架CInject,它具有LogInjector標記方法調用的進入和退出。
或者您可以按照本文中提到的步驟Intercepting Method Calls using IL並使用C#中的Reflection.Emit類創建自己的攔截器。
功能
要擴大Jared的答案,避免代碼重複和包括options for arguments:
private static void LogEnterExit(bool isEnter = true, params object[] args)
{
StackTrace trace = new StackTrace(true); // need `true` for getting file and line info
if (trace.FrameCount > 2)
{
string ns = trace.GetFrame(2).GetMethod().DeclaringType.Namespace;
string typeName = trace.GetFrame(2).GetMethod().DeclaringType.Name;
string args_string = args.Length == 0 ? "" : "\narguments: [" + args.Aggregate((current, next) => string.Format("{0},{1};", current, next))+"]";
Console.WriteLine("{0} {1}.{2}.{3}{4}", isEnter ? "Entering" : "Exiting", ns, typeName, trace.GetFrame(2).GetMethod().Name, args_string);
}
}
static void LogEnter(params object[] args)
{
LogEnterExit(true, args);
}
static void LogExit(params object[] args)
{
LogEnterExit(false, args);
}
使用
static void DoSomething(string arg1)
{
LogEnter(arg1);
Console.WriteLine("Executing DoSomething");
LogExit();
}
輸出
在控制檯中,這將是如果DoSomething
以「blah」作爲012運行,則輸出
Entering Program.DoSomething
arguments: [blah]
Executing DoSomething
Exiting Program.DoSomething
- 1. 如何在Java中自動記錄方法的入口/出口?
- 2. 製作一個平滑的動態入口,出口,以及
- 3. EXE出口靜態庫出口以及
- 4. 以接口爲參數的方法
- 5. 自動記錄方法進入和退出
- 6. 接口方法和參數約束
- 7. JAVA方法參數和接口
- 8. RetroFit接口方法參數
- 9. .NET:記錄沒有AOP的入口/出口?
- 10. Java記錄器的輸入/退出方法中的參數
- 11. 記錄接口及其實現
- 12. 自我記錄REST接口
- 13. 插入記錄到接口
- 14. MS Access日誌記錄用戶網絡入口和出口時間
- 15. 在@ModelAttribute註釋方法內自動記錄@PathVariable註釋參數
- 16. C#方法參數值記錄自動化
- 17. 出口DEFTYPE方法
- 18. 接口作爲方法的參數
- 19. 與不同方法的接口參數
- 20. GCS來自App引擎實例的入口和出口費用
- 21. netem和tcpdump的回送接口不同的入口和出口
- 22. 90天窗口+/- 14天反覆出現以及如何查找匹配記錄
- 23. 出口NDB數據存儲記錄,以雲存儲CSV文件
- 24. 自動刪除聯合數據以及刪除記錄?
- 25. 進入和退出函數時自動記錄(Log4Net)
- 26. 出口進口速記
- 27. 我可以確定我自己的C#入口點方法嗎?
- 28. 出口記錄的Excel工作表
- 29. 出口重複記錄的字段
- 30. C#自動鑄造接口方法
此代碼順利使用此代碼捕獲的參數值 http://stackoverflow.com/a/6928253/1267778。所以我有類似logService.LogEnter(arg1,arg2,arg3)。好東西 – parliament 2014-10-17 02:44:29