PostSharp.Samples / PostSharp.Samples.AutoDataContract / AutoDataContractAttribute.cs
using PostSharp.Aspects;
using PostSharp.Extensibility;
using PostSharp.Reflection;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.Serialization;

namespace PostSharp.Samples.AutoDataContract
{
  // We set up multicast inheritance so  the aspect is automatically added to children types. This is optional.
  [MulticastAttributeUsage(Inheritance = MulticastInheritance.Strict)]

  // Since we want the aspect to be applied on types, we derive our class from TypeLevelAspect.
  // If you want to have a project-wide aspect provider, derive the class from AssemblyLevelAspect.
  public class AutoDataContractAttribute : TypeLevelAspect, IAspectProvider
  {
    // This method is called at build time and should just provide other aspects.

    public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
    {
      var targetType = (Type) targetElement;

      var introduceDataContractAspect =
        new CustomAttributeIntroductionAspect(
          new ObjectConstruction(typeof(DataContractAttribute).GetConstructor(Type.EmptyTypes)));

      var introduceDataMemberAspect =
        new CustomAttributeIntroductionAspect(
          new ObjectConstruction(typeof(DataMemberAttribute).GetConstructor(Type.EmptyTypes)));


      // Add the DataContract attribute to the type.
      yield return new AspectInstance(targetType, introduceDataContractAspect);

      // Add a DataMember attribute to every relevant property.
      foreach (var property in
        targetType.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
      {
        if (property.CanWrite && !property.IsDefined(typeof(NotDataMemberAttribute)))
        {
          yield return new AspectInstance(property, introduceDataMemberAspect);
        }
      }
    }
  }
}