Skip to content

ImplementingAdvices

jacobbarnes-ac edited this page May 19, 2022 · 8 revisions

Implementing advices

A very small theory on it

In our implementation:

  • The advices are attribute implementations
  • The pointcuts are attributes applied to method, property, type or assembly

Let's get practical

Method advices

Here is a first method advice:

public class ADummyMethodAdvice : Attribute, IMethodAdvice
{
    // your only duty is to implement the method below...
    public void Advise(MethodAdviceContext context)
    {
        // ... and optionnally call the original method (this is usually a good idea)
        context.Proceed();
    }
}

Some special method advices are property advices:

public class ADummyPropertyAdvice : Attribute, IPropertyAdvice
{
    public void Advise(PropertyAdviceContext context)
    {
        if(context.IsGetter)
        {
            context.Proceed();
            // you can check the return value here, by using context.ReturnValue
        }
        else
        {
            // you can check the setter value here, by using context.Value
            context.Proceed()
        }
    }
}

There is also a specialization for parameter advices (please note that parameter advices can be applied at method level, in which case they apply to all method parameters):

public class ADummyParameterAdvice : Attribute, IParameterAdvice
{
    public void Advise(ParameterAdviceContext context)
    {
        if (context.IsIn)
        {
            // input or ref parameters can be checked here
        }
        context.Proceed();
        if (context.IsOut)
        {
            // output or ref parameters and return value can be checked here
        }
    }
}

Info advices

A method info advice

public class ADummyMethodInfoAdvice : Attribute, IMethodInfoAdvice
{
    public void Advise(MethodInfoAdviceContext context)
    {
        // do what you want here
    }
}

And a property info advice:

public class ADummyPropertyInfoAdvice : Attribute, IPropertyInfoAdvice
{
    public void Advise(PropertyInfoAdviceContext context)
    {
        // do what you want here
    }
}

Weaving advices

public class MethodWeavingAdvice : Attribute, IMethodWeavingAdvice
{
    public void Advise(MethodWeavingContext context)
    {
        // we add a property, named after the target method.
        context.AddPublicAutoProperty(context.TargetMethodName + "_Friend", typeof(string));
        // and we also renamed the target method. All calls are preserved.
        context.TargetMethodName += "_Renamed";
        // also, extra initializers can be added to target class
        // those initializeds will be invoked at the end of constructors
        context.AddInitializer(Initializer);
    }

    public static void Initializer(object instance)
    {
        // you can add extra initialization from here
    }
}

Markers for advices

There are a few special attributes that can be applied to advices:

  • [AbstractTarget]: the methods where this advice is applied have their original code removed, so context.ProceedAdvice() can not be called (it will throw an exception)
  • [Priority]: allows to give advice a priority, so Mr.Advice ensures at runtime that advices are invoked by descending priority. Default priority (when this attribute is not used) is 0.

End of part one (their greatest hits)

Please note that a single class can implement multiple advice interfaces (info advice and method advice, for example).

You can now learn how to use those advices.