我希望能够使用自定义Trace
属性修饰任何方法,并且应该在编译时将一些代码注入到该方法中。
例如:
[Trace]
public void TracedMethod(string param1)
{
//method body
}
应该成为:
public void TracedMethod(string param1)
{
Log.Trace("TracedMethod", "param1", param1);
//method body
}
在这种情况下,注入的代码取决于方法名称和方法参数,因此应该可以推断出这些信息。
有谁知道如何做到这一点?
答案 0 :(得分:13)
要在C#中进行面向方面编程,您可以使用PostSharp。
(The homepage甚至会显示Trace
示例,就像您要求的那样!)
答案 1 :(得分:2)
这可以通过程序转换系统轻松完成。
DMS Software Reengineering Toolkit是一个通用程序转换系统,可以与多种语言(C ++,COBOL,Java,EcmaScript,Fortran,...)一起使用,也可以与C#一起使用。
DMS解析源代码,构建抽象语法树,并允许您应用源到源模式,将您的代码从一个C#程序转换为另一个具有您希望的属性的程序。完全完成您指定的任务的转换规则是:
domain CSharp.
insert_trace():method->method
"[Trace]
\visibility \returntype \methodname(string \parametername)
{ \body } "
->
"\visibility \returntype \methodname(string \parametername)
{ Log.Trace(\CSharpString\(\methodname\),
\CSharpString\(\parametername\),
\parametername);
\body } "
引号(“)不是CSharp引号;相反,它们是”域引号“,并表示引号内的内容是CSharp语法(因为我们说”域CSharp“)。\ foo符号是元语法。
此规则匹配代表您使用 [Trace]注释指定的方法的AST,并将该AST重写为跟踪形式。然后将生成的AST重新打印回源表单,您可以编译。您可能需要其他规则来处理其他参数组合;实际上,您可能会将参数处理概括为为每个标量参数生成(在可行的情况下)字符串值。
应该很清楚,你可以做更多的事情,而不仅仅是记录这个,而不仅仅是面向方面的编程,因为你可以表达任意变换,而不仅仅是前后行动。