Rob Nicholson
Rob Nicholson

Reputation: 1982

Custom attribute missing when using PostSharp based attributes

Newbie to PostSharp. Consider following code:

using System;
using PostSharp.Aspects;

namespace PostSharp1 {

    [AttributeUsage(AttributeTargets.Property)][Serializable]public class Field1Attribute : System.Attribute { }
    [AttributeUsage(AttributeTargets.Property)][Serializable]public class Field2Attribute : LocationInterceptionAspect { }

    public class Person {
        [Field1][Field2]public string Name { get; set; }
    }

    class Program {

        static void Main(string[] args) {

            var Friend = new Person();
            Friend.Name = "Fred Bloggs";

            var Properties = Friend.GetType().GetProperties();
            Console.WriteLine("Properties: " + Properties.Length);
            var Count1 = 1;
            foreach (var Property in Properties) {
                var CustomAttributes = Property.GetCustomAttributes(false);
                Console.WriteLine("  Property #" + Count1++ + ": " + Property.Name + ", # custom attributes = " + CustomAttributes.Length);
                var Count2 = 1;
                foreach (System.Attribute CustomAttribute in CustomAttributes) {
                    Console.WriteLine("    Attribute #" + Count2++ + ": " + CustomAttribute.ToString());
                }
            }
        }

    }

}

A made-up example that uses Reflection to list the custom attributes on the properties of a small Person class.

The program lists Field1Attribute (based upon System.Attribute) but Field2Attribute appears to have been stripped out as it's not listed.

Just trying to understand the mechanism here and why the LocationInterceptionAspect derived attribute is missing.

Upvotes: 2

Views: 206

Answers (1)

Rob Nicholson
Rob Nicholson

Reputation: 1982

Strange how sometimes just writing up the question allows you to research the answer. This is "by-design" - aspects (which are derived from System.Attribute) are removed after they have been applied. Kind of makes sense as PostSharp is really all about build time. However, it's possible to prevent them being removed as covered in the documentation:

1.1.5. Reflecting Aspect Instances at Runtime

Attribute multicasting has been primarily designed as a mechanism to add aspects to a program. Most of the time, the custom attribute representing an aspect can be removed after the aspect has been applied. By default, if you add an aspect to a program and look at the resulting program using a disassembler or System. Reflection, you will not find these corresponding custom attributes.

If you need your aspect (or any other multicast attribute) to be reflected by System.Reflection or any other tool, you have to set the MulticastAttributeUsageAttributePersistMetaData property to true. For instance:

[MulticastAttributeUsage( MulticastTargets.Class, PersistMetaData = true )]
public class TagAttribute : MulticastAttribute
{
public string Tag;
}

Upvotes: 2

Related Questions