XPO Auto Properties and PostSharp 2.1 Starter Edition

I've been using the solution from http://xpoautoproperties.codeplex.com/ for years.  But last week I needed to update an application to .NET 4.0 so that I could use signalR.  Problem was that xpoautoproperties used PostSharp 1.5 which does not support .NET 4.0.  So I went over to the PostSharp site and saw that there was a free starter edition.  Being a stingy bastard I decided to have a look.  After some swearing and head scratching I produced the following that works for me.


    [Serializable]
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)]
    [MulticastAttributeUsage(MulticastTargets.Property, 
        TargetMemberAttributes = MulticastAttributes.NonAbstract | MulticastAttributes.Public)]
    public sealed class XpoAutomaticPropertiesAttribute : LocationInterceptionAspect
    {
        public MethodInfo OnSetPropertyValueMethod;

        public override void OnSetValue(LocationInterceptionArgs args)
        {
            // Don't go further if the new value is equal to the old one.
            // Use object.Equals, because == operator on objects always checks reference equality, but object.Equals() is virtual
            if ((args.Value == null) && (args.GetCurrentValue() == null))
                return;
            if ((args.Value != null) && (args.GetCurrentValue() != null) && args.Value.Equals(args.GetCurrentValue()))
                return;

            args.ProceedSetValue();

            var ignoreAttributes = (XpoIgnoreAutomaticPropertyAttribute[])args.Location.PropertyInfo.GetCustomAttributes(typeof(XpoIgnoreAutomaticPropertyAttribute), true);
            if (ignoreAttributes.Any())
                return;

            // Invoke method OnSetPropertyValue (our, the base one, or the overridden one).
            OnSetPropertyValueMethod.Invoke(args.Instance, new object[] { args.Location.Name, args.Value });
        }

        public override void CompileTimeInitialize(PostSharp.Reflection.LocationInfo locationInfo, AspectInfo aspectInfo)
        {
            OnSetPropertyValueMethod = locationInfo.DeclaringType.GetMethod(
                "SetPropertyValue", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
                null,
                new Type[] { typeof(string), typeof(object) },
                null);
        }
    }

Comments

Popular Posts