Wednesday, 20 February 2008

This is the second of a series about how to go about using postcompilation in your solutions. You can read it as a tutorial on how to use PostSharp. I am very much a new to that framework, but the power it provides could seriously change how you build your applications. While working on the EF contrib project, I had to dive into PostSharp, and I hope to share some of the things I learned along the way.

This post introduces the first real step I took: the compound aspect.

The full table of contents:

  • Introducing Entity Framework Contrib- Easy IPoco implementation V 0.1
  • Part II, Postsharp Core versus Postsharp Laos
  • Part III, the compound aspect
  • Part IV, the PocoInterfaceSubaspect
  • Part V, hooking up the weaver
  • Part VI, the EdmScalarWeaver
  • Recap

    We wish to create an attribute that can be placed on top of our ordinary Poco class, that will magically transform it into a class that implements the 3 IPoco interfaces. These are needed by the Entity Framework to do it's work. We will use PostSharp to do this.
    Post 1 introduced the project and post 2 introduced PostSharp.

    The Compound aspect

    I have created an attribute class that can be placed on top of other classes, like so:

        /// <summary>
        /// <para>
        /// Attribute that can be used to decorate normal POCO classes with. It is used to start off a post compilation phase
        /// that will modify the IL of the class. After this phase, the class will implement:
        /// <list type="">
        /// <item>INotifyPropertyChanged</item>
        /// <item>IEntityWithChangeTracker</item>
        /// <item>IEntityWithKey</item>
        /// <item>IEntityWithRelationships</item>
        /// </list>
        /// </para>
        /// <para>
        /// It will also place EDMScalarattributes on your properties.
        /// </para>
        /// <para>This results in a type that is completely ready for consumption by the EntityFramework</para>
        /// </summary>
        [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
        [MulticastAttributeUsage(MulticastTargets.Class, AllowMultiple = false)]
        public sealed class PocoAttribute : CompoundAspect
    ... implementation

    As you can see it inherits from the compound aspect class, from the PostSharp.Laos assembly.

    The compound aspect basically allows you to define other aspects to do the job for you. This is very nice when you want to do more things, but only want to use one aspect.

    By overriding the ProvideAspects method, we can add our other aspects:

      1         public override void ProvideAspects(object element, LaosReflectionAspectCollection collection)
      2         {
      3             // Get the target type.
      4             Type targetType = (Type)element;
      6             // implement the INotifyPropertyChanged interface on the class
      7             collection.AddAspect(targetType, new AddNotifyPropertyChangedInterfaceSubAspect());
      8             // implement the three IPOCO interfaces on the class
      9             collection.AddAspect(targetType, new PocoInterfacesSubAspect());
    10             // inspect the complete class and add EDM scalar attributes to the properties
    11             collection.AddAspect(targetType, new EDMAttributesSubAspect(this.EDMContainerName, Name, NamespaceName, PathToConfigFile));
    13             // iterate the properties
    14             foreach (PropertyInfo property in targetType.UnderlyingSystemType.GetProperties())
    15             {
    16                 if (property.DeclaringType == targetType && property.CanWrite)
    17                 {
    18                     MethodInfo method = property.GetSetMethod();
    20                     if (!method.IsStatic)
    21                     {
    23                         // throw notifypropertychanged events
    24                         collection.AddAspect(method, new OnPropertySetNotifyPropertyChangedSubAspect(property.Name, this.AspectPriority));
    26                         // TODO: possibly refactor to only include edm properties
    27                         // call the changetracker
    28                         collection.AddAspect(method, new OnPropertySetChangeTrackSubAspect(property.Name, this.AspectPriority));
    29                     }
    30                 }
    31             }
    32         }

    As you can see, on line 4 I cast the element parameter to a type. That is the type we have adorned with our attribute (your 'Person' Poco class, for instance). Then, I specify that I want 3 other aspects to work on this type!

    • The AddNotifyPropertyChangedInterfaceSubAspect, will implement the INotifyPropertyChangedInterface. (note: this aspect is added just for simplicity, it has nothing to do with IPoco, so I might remove it).
    • The PocoInterfaceSubAspect, will implement the 3 interfaces (see following post)
    • The EDMAttributesSubAspect, will put EDMScalar attributes on top of our properties, needed by EF to do it's job

    After that, I loop through the properties in our targetType and add aspects to their setters. These will inject methods into the setters to throw the PropertyChanged event and let the EF changetracker know that the property was changed.

    That's all the work this compound aspect does. It just provides aspects to the correct codeblocks. The real work is done inside of these aspects and will be explained in following posts.

    Friday, 15 October 2010 12:25:59 (Romance Standard Time, UTC+01:00)
    That is the type we have adorned with our attribute (your 'Person' Poco class, for instance). Then, I specify that I want 3 other aspects to work on this type!
    Thursday, 25 November 2010 12:42:53 (Romance Standard Time, UTC+01:00)
    That is the type we have adorned with our attribute (your 'Person' Poco class, for instance). Then, I specify that I want 3 other aspects to work on this type!
    Saturday, 04 December 2010 02:46:39 (Romance Standard Time, UTC+01:00)
    Using spent get a bird's-eye view of is known as a reputable technique to generate income on line. Satisfied eye is simply a method of getting settled for your opinion. You are likely to be doing surveys for tremendous businesses like coca cola, Nike, eBay, Google, MacDonald and so forth. This can be a kind of industry investigation analysis. The payment means for many paid for eye sites is by means of paypal or verify and it can be generally executed month to month.
    Saturday, 04 December 2010 02:53:26 (Romance Standard Time, UTC+01:00)
    The 460cc 2009 Launcher UL is obtainable in lofts of 9??, 10.5??, and 12?? (RH Only). The Fujikura Flightspeed Fit-On Gold is available in flexes A, R, S, and X and weighs 50g. The Fujikura Flightspeed Fit-On Red-colored comes in flexes R, S, and X and weighs 60g.
    Saturday, 04 December 2010 03:31:58 (Romance Standard Time, UTC+01:00)
    <a href="">iphone usb cable</a>
    <a href="">iphone usb charger</a>
    <a href="">Protective Leather Case with Magnetic Strap for 9.7' iPad</a>
    <a href="">Protective 'Crocodile Leather' Carrying Bag for Apple 9.7' iPad </a>

    <a href="">digital camera</a>
    <a href="">digital cameras sale</a>
    <a href="">cheapest digital cameras</a>

    <a href="">iPhone Cases</a>
    <a href="">iphone case</a>
    <a href="">iPhone 3G Case</a>
    <a href="">iphone 3g case </a>
    <a href="">iPhone covers</a>
    <a href="">iPhone plastic cases</a>
    <a href="">iphone skin</a>
    <a href="">iphone 3g skin</a>
    Comments are closed.