自动记录方法的进入和退出以及参数?

Xer*_*erx 9 .net logging log4net

有没有办法让我添加日志记录,以便进入和退出方法与参数一起自动记录以用于跟踪目的?我该怎么办?

我正在使用Log4Net.

ckr*_*mer 8

实现这种事情的最好方法是使用拦截,有几种方法可以做到这一点,尽管它们都有点侵入性.一种是从ContextBoundObject派生所有对象. 以下是使用此类方法的示例.另一种方法是使用现有的AOP库之一来实现这一目标.像Castle Project中的 DynamicProxy之类的东西是其中许多的核心.以下是一些链接: Spring.Net PostSharp Cecil

可能还有其他几个,我知道Castle WindsorNinject都在IoC功能之上提供AOP功能.

一旦AOP到位,您只需编写一个拦截器类,将有关方法调用的信息写入log4net.

如果其中一个AOP框架能够为您提供开箱即用的功能,我实际上不会感到惊讶.


Jar*_*red 5

我不确定您的实际需求是什么,但这是一个低租金的选择。它并不完全是“自动”的,但您可以使用 StackTrace 以不需要传递参数的方式剥离您正在寻找的信息 - 类似于 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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以将上面的示例与继承结合起来,使用基类型中的非虚拟公共成员来表示操作方法,然后调用虚拟成员来实际完成工作:

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...
    }
}
Run Code Online (Sandbox Code Playgroud)

再说一遍 - 这并没有太多“自动”,但如果您不需要对每个方法调用进行检测,那么它会在有限的基础上工作。

希望这可以帮助。