Project "Caravela" 0.3 / / Caravela Documentation / Conceptual Documentation / Creating Aspects / Advising Code / Sharing State With Advices

Sharing State with Advices

If you need to share compile-time state between advices, or between advices and your implementation of the BuildAspect method, a few strategies are available to you.

Note

If you need to share run-time state between advices, you have to choose another strategy, for instance introducing a field in the target type and using it from several advices.

Sharing state with an aspect field

A simple way to share state between different aspect methods (both templates or regular compile-time methods) is to simply use a field of the aspect class. You can for instance initialize the field in your implementation of the BuildAspect method and use it from template methods.

The inconvenience of this method is that it is not very flexible. You cannot pass state that is specific to an advice.

Sharing state with the Tags property

If your BuildAspect method needs to pass to a template method some state that is specific to an advice instance, you can construct an instance of the Dictionary<String, object> class and assign all elements of state as tags in the name-value dictionary. In the template method, the tags are available under the meta.Tags dictionary.

Example

using System;
using Caravela.Framework.Aspects;
using Caravela.Framework.Code;

namespace Caravela.Documentation.SampleCode.AspectFramework.Tags
{
    class TagsAspect : MethodAspect
    {
        public override void BuildAspect( IAspectBuilder<IMethod> builder )
        {
            builder.Advices.OverrideMethod(
                builder.Target, 
                nameof(OverrideMethod), 
                tags: new() { ["ParameterCount"] = builder.Target.Parameters.Count });
        }

        [Template]
        private dynamic? OverrideMethod()
        {
            Console.WriteLine($"This method has {meta.Tags["ParameterCount"]} parameters.");
            return meta.Proceed();
        }
    }
}
using System;

namespace Caravela.Documentation.SampleCode.AspectFramework.Tags
{
    class TargetCode
    {
        [TagsAspect]
        void Method(int a, int b)
        {
            Console.WriteLine($"Method({a}, {b})");
        }
    }
}
using System;

namespace Caravela.Documentation.SampleCode.AspectFramework.Tags
{
    class TargetCode
    {
        [TagsAspect]
        void Method(int a, int b)
        {
            Console.WriteLine($"This method has 2 parameters.");
            Console.WriteLine($"Method({a}, {b})");
            return;
        }
    }
}