I will try to phrase this question with as little details as needed, to keep the question brief. Let me know if more details are required.
I have an aspect X on property A which dynamically generates an aspect Y on property B. Property B may be already contain aspects of type Y, and these interact with each other and the generated instance of Y.
I require the instances of Y generated by X, to be present before the non-generated instances of Y are run. Using AspectDependencies I have not been able to make this work. I've place a AspectDependencyPosition.
The aspect dependency I've placed on X is of the form: [AspectTypeDependency(AspectDependencyAction.Order, AspectDependencyPosition.Before, typeof(Y))]
The execution order that I get is: SourceInstanceOfY,X,GeneratedInstanceOfY
While the execution order that I need is: X,SourceInstanceOfY,GeneratedInstanceOfY where the last two may change order.
Is there a way to solve this solution or it not supported by PostSharp?
Thanks, Remy.
By using AspectTypeDependency you specified the ordering between aspects X and Y, but the order for Y instances is still not specified. You can use the ApectPriority property to order individual instances of the Y aspect. You can find the simple example based on your description below:
class TestClass
{
[MyAspectX]
public int PropertyA { get; set; }
[MyAspectY("from attribute", AspectPriority = 2)]
public int PropertyB { get; set; }
}
[Serializable]
public class MyAspectX : LocationInterceptionAspect, IAspectProvider
{
public override void OnGetValue(LocationInterceptionArgs args)
{
Console.WriteLine("X OnGetValue");
base.OnGetValue(args);
}
public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
{
yield return new AspectInstance(
((LocationInfo) targetElement).DeclaringType.GetProperty("PropertyB"),
new MyAspectY("from provider") {AspectPriority = 1});
}
}
[Serializable]
public class MyAspectY : LocationInterceptionAspect
{
private string tag;
public MyAspectY(string tag)
{
this.tag = tag;
}
public override void OnGetValue(LocationInterceptionArgs args)
{
Console.WriteLine("Y OnGetValue " + tag);
base.OnGetValue(args);
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new TestClass().PropertyB);
}
}