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