在.NET中有一种方法可以在调用另一个方法之后但在输入之前自动调用一个方法

时间:2008-10-10 17:22:29

标签: c# .net

我正在寻找的是一种在调用另一个方法之后但在输入之前调用方法的方法。例如:

public class Test {

  public void Tracer ( ... )
  {
  }

  public int SomeFunction( string str )
  {
    return 0;
  }

  public void TestFun()
  {
    SomeFunction( "" );
  }

}

在上面的例子中,我想在TestFun()调用SomeFunction()之后但在输入SomeFunction()之前调用Tracer()。我还想在SomeFunction()上获得反射数据。


我在每个人的答案中都找到了一些有趣的东西。 问题的最佳答案是使用Castle的DynamicProxy;但是,这不是我将要用来解决我的问题,因为它需要在我的项目中添加一个库。我只有一些方法需要“跟踪”,因此我选择采用与动态代理实现方式混合的修改后的“核心”方法。我在下面回答我自己的问题时解释了这一点。

正如我要注意的那样,我将研究其他一些应用程序的AOP和ContextBoundObject类。

8 个答案:

答案 0 :(得分:5)

您可以使用动态代理(例如Castle's DynamicProxy)拦截调用,运行您希望的任何代码,然后根据需要调用您的方法。

答案 1 :(得分:2)

使用*核心方法:

public int SomeFunction(string str)
{
    Tracer();
    return SomeFunctionCore(str);
}

private int SomeFunctionCore(string str)
{
    return 0;
}

许多.NET API使用它(在WPF中很多)。

答案 2 :(得分:2)

使用代表!

delegate void SomeFunctionDelegate(string s);

void Start()
{
  TraceAndThenCallMethod(SomeFunction, "hoho");
}

void SomeFunction(string str)
{
  //Do stuff with str
}

void TraceAndThenCallMethod(SomeFunctionDelegate sfd, string parameter)
{
  Trace();
  sfd(parameter);
}

答案 3 :(得分:1)

您希望了解面向方面编程。这是我在.NET中找到的AOP页面:http://www.postsharp.org/aop.net/

面向方面编程涉及从代码中分离出“横切关注点”。一个例子是日志记录 - 在所有代码中存在(希望)。这些方法是否真的需要了解日志记录?也许不吧。 AOP是研究将这些问题与它们处理的代码分离,并在编译时或运行时将它们注入。我发布的链接包含几个工具的链接,这些工具可用于编译时和运行时AOP。

答案 4 :(得分:1)

.NET有一个名为ContextBoundObject的类,您可以使用它来设置消息接收器来执行调用拦截,只要您不介意从基类派生,这将为您提供所需的内容而不需要依赖库。

答案 5 :(得分:0)

你必须使用某种形式的AOP框架,如SpringFramework.NET来做到这一点。

答案 6 :(得分:0)

如果您需要大规模(即对于程序中的每个函数)执行此操作并且您不希望大幅更改源,您可能会考虑使用.NET Profiling API。它有点毛茸茸,因为你必须构建自由线程的COM对象,但它可以让你对程序的执行有很大的控制。

答案 7 :(得分:0)

这是我选择解决问题的解决方案。由于没有自动(属性)方式来完成这项工作,我觉得它是最不突兀的,并允许通过选择实例化的类来打开和关闭功能。请注意,这不是我问题的最佳答案,但对于我的具体情况,这是更好的答案。

正在发生的事情是我们只是派生出一个有时或者总是被实例化而代替其父类的第二个类。我们想要跟踪(或以其他方式跟踪)的方法在派生类中声明为虚拟和重新实现,以执行我们想要跟踪的任何操作,然后在父类中调用该函数。

public class TestClass {

  public virtual void int SomeFunction( string /*str*/ )
  {
    return 0;
  }


  public void TestFun()
  {
    SomeFunction( "" );
  }

}


public class TestClassTracer : TestClass {

  public override void int SomeFunction( string str )
  {
    // do something
    return base.SomeFunction( str );
  }

}