我对PostSharp很新,所以请引导我找到正确的方向。
假设我有LoggingAspect:
public class LoggingAspect : OnMethodBoundaryAspect
{
private ILog _log;
private string _targetFullName;
}
第一个问题,如果我将_log
声明为static
成员,它是否会在所有LoggingAspect实例中共享?在方面内部使用静态变量是否常见?
现在我通过覆盖CompileTimeInitialize
:
public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
_log = LogManager.GetLogger(method.DeclaringType);
_targetFullName = string.Format("{0}.{1}", method.DeclaringType.Name, method.Name);
}
这里我有点困惑,PostSharp在将我的方面序列化为托管资源时如何保持对logger实例的引用?
此外,我可以在运行时将1}}变量分配给我的_log
变量:
public override void RuntimeInitialize(MethodBase method)
{
_log = LogManager.GetLogger(method.DeclaringType);
}
我应该使用什么方法?编译时还是运行时?它会有什么不同吗?
答案 0 :(得分:0)
您可以在方面类中使用静态字段,当然它将在方面的所有实例之间共享。
但是,大多数方面字段通常是实例字段。在编译项目期间可以计算某些字段的值(例如,示例中为 _targetFullName )。您可能希望在CompileTimeInitialize
方法中初始化这些字段,以避免在运行时进行不必要的计算。
在编译时,PostSharp为应用方面的每个代码元素创建方面类的新实例。在CompileTimeInitialize
对给定实例执行后,它将序列化为程序集受管资源。在应用程序运行时,方面实例被反序列化,并且所有先前计算的字段都将被恢复。
另一方面,对于某些字段,值只能在运行时计算,或者在运行时之前没有实际意义(例如示例中的 _log - 您希望在运行时记录,并且所有日志记录配置也在运行时可用)。您将这些字段标记为[NonSerialized]
,并在RuntimeInitialize
方法中初始化它们的值。
在更复杂的场景中,您还可以为目标类的每个新实例创建一个新的方面实例。在这种情况下,您通常还会实现RuntimeInitializeInstance
方法。
所有这些也在文档文章Understanding Aspect Lifetime and Scope中讨论过。