0
votes

I have been trying PostSharp AOP for a while. I am able to design simple aspects and use them fine. But I am trying to find the best way to achieve this scenario.

Scenario:

  • Log the method on entry and exit.

  • Log developer specified statements within the method.

Assume that I have built an Apsect(LogMethodAspect) that logs the method during entry an exit.

However, now I want to log a specific statement. I want this statement to be part of the same log.

Options:

  1. Create another aspect (LogStatementAspect) that will log the parameters, now call this method when I want to log a statement.
  2. Create an interface with one method called "LogThis" and in the assembly specify an aspect specifically for "LogThis" method.

I am trying to find an appropriate way such that it will require the least amount of dependency.

Can you create an aspect on a statement? Can you call an underlying Aspect method directly?

Any help would be great.

Sample pseudo code:

[LogMethodAspect]
Mothod1 (input1, input2)
{
   Do Something

   "Log this info" // How can I re-use the logging methodology already created in the aspect - LogMethodAspect


   Do Something more
}
1

1 Answers

0
votes

In general, it' not possible to apply an aspect to a specific statement inside the method. Also, aspects are supposed to be orthogonal to your application logic, and so the code inside your method should not be coupled to the aspect applied on this method through direct method calls.

If the specific statement you want to log is also a method call, then you should be able just to apply the same aspect on that invoked method. You can apply the aspect even if the method is in the external assembly you don't have the source code for. In that case, you need to set AttributeTargetAssemblies property when applying the aspect in your assembly:

[assembly:LogMethodAspect(AttributeTargetAssemblies="SomeAssemblyName", AttributeTargetTypes = "...")]

If you want to log not a method call but some arbitrary info, I would suggest to implement an underlying logging provider that will be called from the aspect and from the points in your code where you need to log that additional info.

public interface ILogger
{
    void Log(string message);
}

[Serializable]
public class LogMethodAspect : OnMethodBoundaryAspect
{
    private ILogger logger;

    public override void RuntimeInitialize(MethodBase method)
    {
        this.logger = // get the shared logger instance
    }

    public override void OnEntry(MethodExecutionArgs args)
    {
        // ...
        this.logger.Log("Entering: " + method_name + arg_values);
    }
}

class Class1
{
    [LogMethodAspect]
    void Method1 (input1, input2)
    {
        // Do Something

        // using the same shared logger
        logger.Log("Log this info")

        // Do Something more
    }   
}