0
votes

I am quite new to PostSharp, so please guide me to the correct direction.

Let's say I have LoggingAspect:

    public class LoggingAspect : OnMethodBoundaryAspect
    {
        private ILog _log;

        private string _targetFullName;
}

First question if I declare _log as static member, would it be share across all LoggingAspect instances? does it common to use static variables inside the aspects?

Now I use compile time initialization by overriding CompileTimeInitialize:

public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
{
    _log = LogManager.GetLogger(method.DeclaringType);
    _targetFullName = string.Format("{0}.{1}", method.DeclaringType.Name, method.Name);
}

Here I am a bit confused, how does PostSharp keeps reference to logger instance when it serialize my aspect to managed resource?

Beside, I can assign logger to my _log variable during run-time:

public override void RuntimeInitialize(MethodBase method)
{
    _log = LogManager.GetLogger(method.DeclaringType);
}

What approach should I use? Compile-time or run-time? does it make some difference at all?

1
I can't answer any of your questions unfortunately but I do know how I've answered (for myself) similar questions I've had about Postsharp, decompiling. Go and download one of the decompilers for .NET out there, like Jetbrains dotPeek and decompile a basic program you've written using Postsharp. It should tell you quite a bit about how they're doing it. Try applying the aspect to two different classes and try to spot the static members, see if they're per-type or shared or what not. - Lasse V. Karlsen

1 Answers

0
votes

You can use a static field in your aspect class, and of course it will be shared between all the instances of the aspect.

However, most of the aspect fields are usually instance fields. The values for some of the fields can be computed during the compilation of the project (e.g. _targetFullName in your example). You would want to initialize these fields in the CompileTimeInitialize method to avoid unnecessary computations at run-time.

At compile-time PostSharp creates a new instance of your aspect class per each code element where the aspect is applied. After CompileTimeInitialize executes on the given instance, it is serialized to the assembly managed resource. During application run-time the aspect instance is deserialized and all the previously computed fields are restored.

On the other hand, for some of the fields the value can be computed only during run-time, or it doesn't have real meaning until the run-time (e.g. _log in your example - you want to log at run-time and all the logging configuration is available at run-time as well). You mark these fields as [NonSerialized] and initialize their values in RuntimeInitialize method.

In more complex scenarios you can also have a new instance of the aspect created for each new instance of the target class. In this case you also usually implement RuntimeInitializeInstance method.

All this is also discussed in the documentation article Understanding Aspect Lifetime and Scope.