我有很多类调用说Trace.WriteLine(“LogSomethingClassSpecific”),各种各样的方法。现在我希望其中一些类能够像这样进行所有Trace调用:Trace.WriteLine(“LogSomethingClassSpecific”,“CategoryA”)
但是!我想从一个分类程序类外部实现这个;无需在每个特定类中查找和修改每个Trace调用。
Class1,Class2,Class3,可能会也可能不会使用跟踪调用
使用添加的参数“CategoryA”调用使用Class2和Class3调用所有现有Trace调用的独立ControllerClass。同时保留了轻松更改目标类的灵活性。
使用某些属性和面向方面编程(AOP)库可能会成为可能吗? 例如 控制班可以specify which classes to target:
[assembly: Categorizer("CategoryA", AttributeTargetTypes = "Namespace.ClassB")]
然后intercept all Trace.WriteLine calls with PostSharp
但我不知道提取调用上下文以确定调用类是否已标记为包含“CategoryA”的方法?
或者有其他方法可以实现这一目标吗?
感谢任何想法。
答案 0 :(得分:1)
有几种方法可以解决这个问题,但我假设你在像if / else构造这样的地方调用Trace,所以这就是你要做的事情(至少,是什么)我想你要求了)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PostSharp.Aspects;
using System.Diagnostics;
[assembly: ConsoleApplication2.TraceIntercept(AttributeTargetAssemblies = "System", AttributeTargetTypes = "System.Diagnostics.Trace")]
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
ExampleA ex = new ExampleA();
ex.Method1();
Console.ReadKey();
}
}
public class ExampleA
{
public void Method1()
{
Trace.Write("Test");
}
}
[Serializable]
[TraceIntercept(AttributeExclude = true)]
public class TraceIntercept : MethodInterceptionAspect
{
private bool addArgument;
private string typeName = string.Empty;
public override void OnInvoke(MethodInterceptionArgs args)
{
CheckInvocationPoint();
if (addArgument)
{
//Do work. Change arguments, etc.
}
args.Proceed(); // Proceed with Trace
}
private void CheckInvocationPoint()
{
if (string.IsNullOrEmpty(this.typeName))
{
StackTrace s = new StackTrace();
StackFrame f = s.GetFrame(2);
string className = f.GetMethod().DeclaringType.Name;
if (classsName.Equals("ExampleA"))
{
addArgument = true;
}
}
}
}
}
这将拦截对System.Diagnostics.Trace方法的调用,而是调用TraceIntercept.OnInvoke方法,您可以在其中操作Trace调用。这种方式的工作方式是PostSharp只需用对方面的调用替换对Trace.Write的调用。
编辑:据我所知,没有办法获取目标方法的实际调用点。这意味着您必须在运行时进行一些反射。我已经更新了代码以使用堆栈跟踪。您只需要执行一次(每种类型),因为方面生命周期将是每个类型而不是每个实例,所以您只需要一次点击。这不是我会怎么做,但我认为这将用于调试目的。