Monday, 15 December 2008

Double Click to Open Visual Studio Solutions in Vista/2008

For a while I have been running Visual Studio under Vista (x32) and now I’m using Workstation 2008 (very happily too!).   I have UAC on, but have a policy setting to automatically elevate without showing a prompt.  (I absolutely can’t live with the dialogs…see here and here for more info).

I have also Visual Studio set to run as administrator, and that’s where the problem starts: I have not been able to open solution files by double clicking them. 

I am very grateful to “Sajeev Prasad / Arun Arcot” response to this post for the solution.

Basically, set both IDE and the loader (%programfiles%\Common Files\Microsoft Shared\MSEnv\VSLauncher.exe) to run as administrator and you can then double click to open solutions.

Thanks Sajeev and Arun!

ReSharper Plugins

I’ve been using ReSharper since it’s first EAP release (late 2003 or early 2004, if I am right) and quite simply would not want to code without it.

ReSharper is a platform that can be easily extended and it is worth noting that there are a number of excellent plugins available that to make your ReSharper experience even better.

I mentioned Scout in an earlier post, but there are plugins for NHibernate, Gallio, xUnit and also for stuff like helping extract resources for internationalisation.

Check here for more details.

XML Editor - Liquid XML Studio

I’ve just started using a great XML editor: Liquid XML Studio.  I used it when creating some XSDs the other day.  It’s really easy to use, and has a great graphical interface too. 

The thing I really really like is the feature to generate an instance of the schema.  The only other tool I’m aware of that does this is the BizTalk schema editor – but that’s a bit more of a heavyweight tool than I usually need!

It also has Visual Studio integration (with the visual editor), XPath expression builder, documentation generation and a web service browser.  It’s not cheap, but there is a free feature limited Community Edition.  There’s also the high end Developer Edition that adds a load of muscle for people working with more complex schemas, such as the OASIS schemas.

Joyful Reflections - ReSharper Scout

I’ve just found an excellent ReSharper plugin called Scout.  This lovely little beast will open Reflector when you choose Go to Declaration.  The thing I really love is that Scout also takes care of loading the appropriate assembly in Reflector.  I previously had to load the assembly in Reflector before I could browse it, which took time.  Scout makes this process seamless.

All you have to do is right click and select Go to Declaration:

Selecting the "Go to Declaration" menu item

Then you get taken to the item in Reflector and the correct assembly is loaded:

reflector

Scout will also take you to the Dotnet source code – but I haven’t got around to that yet!  You can find lots of other ReSharper plugin goodness here.

Saturday, 29 November 2008

Update on XPO and One-Way Associations

I stated in a previous post that XPO would be supporting one-way multi associations.  Unfortunately, this is now not the case.  At the time I wrote the previous post, Developer Express had marked my request as accepted, but have now changed that to rejected.

The guys at Developer Express support say that having a two-way association in your object model is fundamental to XPO multiple associations and, as my request was only to simplify code, the feature is now not to be implemented.  The bottom line from them was:
"To sum it up, we think that the current design of one-to-many associations in XPO is reliable and transparent. We are not going to change it, unless we have strong arguments for doing so."
Well, although it's a shame that it's not going to be implemented, you can't argue than that!

You can find the request thread here (but may need to register).  If you still want to keep your XPO code clean, you can use some IL enhancement with PostSharp - details here.

Thursday, 20 November 2008

Why Support One-Way Multiple Associations?

This post is to answer a question from the Developer Express support team as to why I have requested that XPO support one-way multiple associations. The primary reason for my request is to reduce code noise. When you do not want a reverse association in your model, then you should not be forced to put it in. Using the example from my previous post, if all you need is a one-way association you should be able to write:

  public class Customer : XPObject
  {
    public XPCollection Orders { get; }
  }
  public class Order : XPObject
  {
  }

However, as XPO currently requires you to implement a two-way association in your object model. You have to write something like this:

  public class Customer : XPObject
  {
    [Association("CustomerOrders")]
    public XPCollection Orders { get; }
  }
  public class Order : XPObject
  {
    [Association("CustomerOrders")]
    public Customer Customer;
  }

XPO has made me:
  • Add an attribute to my association property.
  • Give that attribute a unique string to identify the association.
  • Add a new property to my linked type.
  • Add an attribute to this new property.
  • Give this attribute the same string so as to identify it is part of the association.
I have no problem with doing that when I need the association to be two-way. Indeed, XPO does some good things for me when I do need this: it maintains the linked states of the linked instances, which is a great help! In other words, when the Association attribute is used as above, adding an order to a customer's orders will automatically set the order's customer; removing the customer from the order's customer property will remove the order from the customer's orders property. Very nice to have and certainly removes code that I would need to write.

You are probably looking at the above example and thinking that you would naturally have an association from order to customer, and I would agree. However, let's say that you have a requirement to show the recently ordered products against the customer. One way of implementing this would be:

  public class Customer : XPObject
  {
    public XPCollection RecentProducts { get; }
  }

In this circumstance, I would not want to have to implement a reverse association:

  public class Customer : XPObject
  {
    [Association("CustomerRecentProducts")]
    public XPCollection RecentProducts { get; }
  }

  public class Product : XPObject
  {
    [Association("CustomerRecentProducts")]
    public XPCollection Customers { get; }
  }

In this case I would consider the reverse association to be worse than code noise - it is structurally worng and simply should not be there! Maybe we should be suspicious of the Customer.RecentProducts association in the first place too, but that's another story!

Another time when being forced to implement a reverse association is when the two classes are in different assemblies. I would have to move the classes to avoind a circular reference. Maybe I should ask for XPO to support persistence by interface too...


Monday, 10 November 2008

Express Persistent Objects (XPO) to Support One-Way Multiple Associations

Update December 2008: this has changed and is no longer to be supported.  See here for details.

I'm happy to say that Developer Express have now accepted my request to support one-way multiple associations in XPO.  See here for more details.

Friday, 31 October 2008

Using PostSharp to Allow One-Way Multiple Associations in XPO

The Express Persistent Objects (XPO) ORM from Developer Express does not support one way associations with multiplicity greater than one.  Each collection association from a type must have a corresponding reverse association from the linked type.  The reverse link can be either a unary or a collection (making either a one-many or many-many association, respectively).

I put in a request for one-way multi associations here (you may need to register to view).  The response I got back was basically that implementing one-way multi associations would "break existing functionality and this approach contradicts with the XPO concepts".  I think that this is a shame, but there you go.

So, given that I want this feature, I'm going to find the middle ground: let's have one-way associations, but use PostSharp to implement the extra code to keep XPO happy.

The Problem:
I want to be able to write this as valid XPO code:

   public class Customer : XPObject
   {
      public XPCollection Orders { get; }
   }

   public class Order : XPObject
   {
   }

 But XPO wants me to add the other end of the link to Order and to also add associated attributes:

   public class Customer : XPObject
   {
      [Association("CustomerOrders")]
      public XPCollection Orders { get; }
   }

   public class Order : XPObject
   {
      [Association("CustomerOrders")]
      public Customer Customer;
   }

So, for my one-way association there must be another property or field on the linked class as well as marking each participting property(or field with the Association attribute. Not a huge amount of extra code and not an unreasonable amount either!

(Also, it's worth noting here that I am again using PostSharp to let me use automatic properties with XPO here - there is a little more required for normal XPO code.  See my previous posts for more details on how this is done.)

A Solution:
We're going to use PostSharp to generate the reverse link for us and to add the associations that XPO requires.  Basically, I am going to write code as in the first section above and get PostSharp to enhance it at compile time so that it is actually like the second section.  Specifically, I'm going to use PostSharp to:
  • Add a public field to a class.
  • Add an attribute to this new field.
  • Add an attribute to an existing property.
Some Caveats:
If you care about the reverse link, you will want to implement it yourself as is usual in XPO.  The way we are doing it here means that the generated reverse link will not be visible at design time from inside of its own assembly (but it will be from outside the assembly).

Also, the current implementation is not compatible with the Compact Framework or Silverlight.  For this you will need to use the upcoming version 1.5 of PostSharp - more details here.

Approach
 As you will see from the PostSharp web site, PostSharp is made up of two main sections - PostSharp.Core and PostSharp.Laos.  PostSharp.Laos is a plugin on top of PostSharp.Core that simplifies a lot of the common tasks in AOP.  PostSharp.Core is the main engine that enchances your code at compile time.  It is both powerful and deep, and I am certainly not an expert in its use!  However, despite all the power and depth, it is also fairly accesssible.

The PostSharp website uses the lovely term "Pay-As-You-Use Complexity" for PostSharp - you can acheive pretty much anything you want and the common tasks are made fairly simple (by PostSharp.Laos), while other tasks may require you to gain some more knowledge of the inner workings of PostSharp (meaning PostSharp.Core). In my previous articles about PostSharp, we used PostSharp.Laos, for this task we are going to use PostSharp.Core.

In this article, I'm going to show how to add fields and attributes to classes using PostSharp.Core.  I was inspired by Ruurd Boeke's articles, which you can find here.  Ruurd uses PostSharp to enchance POCO classes for the Entity Framework use and goes a lot further with PostSharp than I do here.  I highly recommend reading Ruurd's articles for more detailed information.

Let's now have a look what we need to do to get PostSharp to do what we want.  I'm going to break this down into three sections:


Stage 1 - Attach Aspects
The first step is to create a CompoundAspect as we have done before.  The job of this attribute is going to be to add other PostSharp aspects to our classes.  The other aspects will then be picked up and used by PostSharp.Core.  The ProvideAspects method looks like this:

1 public override void ProvideAspects(
    object element, 
    LaosReflectionAspectCollection collection)
2 {
3     var targetType = (Type) element;
4      foreach (var property in targetType.UnderlyingSystemType
         .GetProperties()
         .Where(info => info.DeclaredIn(targetType) &&
                info.IsOneWayAssociation()))
5    {
6      var fieldName = GetGeneratedFieldName(property);
7      collection.AddAspect(
         property.GetCollectionTargetType(),
         new OtherEndFieldSubAspect(
           targetType.FullName,
           fieldName, 
           fieldName));
8
9      collection.AddAspect(
         targetType, 
         new AssociationAttributeSubAspect(
           property.Name, 
           fieldName));
10    }
11 }

In line 4 we use a bit of LINQ to iterate through the properties of our target type that we are interested in enchancing and then in line 6 we call a helper method to get the name of the field we want to generate.  In lines 7 and 9 we add the aspects.  In line 7 we add an aspect to the type at the other end of our collection and pass it the name of the type of the field we want to add, along with a field name and a string to be passed to the association attribute that we will add later.  Note that we are using an extension method helper (GetCollectionTargetType) to get the type at the other end, although this is nothing more than normal reflection code.  Next, in line 9, we add another aspect to the type that is declaring the collection property, passing it the name of the property that will be enchaned and a string that we will pass to the attribute that we add to the property.

So, we have used PostSharp.Laos to add aspects to our classes.  These aspects contain some information that we will use later.  In fact, as you can see below, the aspects that we have added contain little else other than the information we want to use later.

public class OtherEndFieldSubAspect : ILaosTypeLevelAspect
{
   public OtherEndFieldSubAspect(
     string fieldTypeName, 
     string fieldName, 
     string associationName)
   {
      FieldTypeName = fieldTypeName;
      FieldName = fieldName;
      AssociationName = associationName;
   }

   public void CompileTimeInitialize(Type type) {   }

   public bool CompileTimeValidate(Type type)
   {
      return true;
   }

   public void RuntimeInitialize(Type type) { }

   public int AspectPriority
   {
      get { return int.MinValue; }
   }

   public string AssociationName { get; set; }
   public string FieldName { get; set; }
   public string FieldTypeName { get; set; }
}
public class AssociationAttributeSubAspect : ILaosTypeLevelAspect
{
   public AssociationAttributeSubAspect(
     string propertyName, string associationName)
   {
      PropertyName = propertyName;
      AssociationName = associationName;
   }

   public void CompileTimeInitialize(Type type)    { }

   public bool CompileTimeValidate(Type type)
   {
      return true;
   }

   public void RuntimeInitialize(Type type) { }

   public int AspectPriority
   {
      get { return int.MinValue; }
   }

   public string AssociationName { get; set; }
   public string FieldName { get; set; }
   public string PropertyName { get; set; }
}

Note that these tasks implement ILaosTypeLevelAspect as we are applying the aspects to types.

Stage 2 - Create a Weaver Task

PostSharp's weaver is what we are going to use to create the new field and add the custom attributes.  The public parts of PostSharp are LGPL and can therefore be freely distributed under any license you choose, whereas PostSharp.Core is licensed under the copyleft GPL, and so you cannot distribute PostSharp.Core in another GPL application.  So, if we want to use this commercially, the weaver needs to be split out from the main distribution if the software is going to be used commercially.  This is not a problem as the enhancements happen at compile time and the designer of PostSharp, Gael Fratieur has made this easy for us to seperate PostSharp.Core!  The basis of this is to use PostSharp "tasks" to tell PostSharp.Core what to do at compile time.  A task has a name and points to a weaver implementation that will handle the task.  You configure the tasks in XML as below:



 
            Implementation="Weaver.WeaverFactory, Weaver">
 


The task called WeaveTwoWayAssociations is handled by the type Weaver.WeaverFactory which can be found in the assembly called Weaver.  This file and the rest of the weaver code sits in a seperate project.  Other projects find this by adding the weaver to the search path and adding an assembly level attribute to the project where we defined our AssociationAttributeSubAspect and OtherEndFieldSubAspect aspects.  We also add the weaver project's output folder to each referencing projects search path (inside project | properties).  The assembly attribute looks like this:

[assembly: PostSharp.Extensibility.ReferencingAssembliesRequirePostSharp("WeaveTwoWayAssociations", "Weaver")]
[assembly: InternalsVisibleTo("Weaver")]
Note that the task name and the assembly in which it can be found are indicated.  We also have to allow the weaver to reference our internals!  Also, note that PostSharp has another, more portable, mechanism to tell reference the weaver files, as described in Ruurd's article.  For whatever reason, I could not get this to work and so have just added the reference path.  You will need to change this path on your machine or you will get compile errors about not being able to find a plugin:



Okay, so we've now got a task setup to let PostSharp's weaver loose on our aspects.   We now just need to define what the weaver needs to do.

Stage 3 - Do the Weaving
In our configuration we said that the task called WeaveTwoWayAssociations was handled by the class Weaver.WeaverFactory.  WeaverFactory implements ILaosAspectWeaverFactory and looks like this:

public class WeaverFactory : Task, ILaosAspectWeaverFactory
{
  public LaosAspectWeaver CreateAspectWeaver(ILaosAspect aspect)
  {
     if (aspect is OtherEndFieldSubAspect)
     {
        var addField = (OtherEndFieldSubAspect)aspect;
        return new AddFieldWeaver(
          addField.FieldTypeName, 
          addField.FieldName,
          addField.AssociationName);
     }

     if (aspect is AssociationAttributeSubAspect)
     {
        var addAttribute = (AssociationAttributeSubAspect)aspect;
        return new PropertyAttributeWeaver( 
          addAttribute.PropertyName,
          addAttribute.AssociationName);
     }
     return null;
  }
}

Ttrue to its name, the factory is responsible for providing instances of types that can do some work for us.  Note that the factory is looking for the aspects that we added in stage 1.  When a OtherEndFieldSubAspect is encountered, an instance of AddFieldWeaver is created and returned to PostSharp.  When a AssociationAttributeSubAspect is encountered, an instance of PropertyAttributeWeaver is created and returned to PostSharp.

So, as indicated above, the work of adding a field is done by the AddFieldWeaver class.  You might be expecting this class to be pretty complex and have lots of IL in it.  If you are, you're in for a surprise as it's actually really clean and straight forward:

public class AddFieldWeaver : TypeLevelAspectWeaver
{
   public AddFieldWeaver(
     string fieldTypeName, string fieldName, 
     string associationName)
   {
      FieldTypeName = fieldTypeName;
      FieldName = fieldName;
      AssociationName = associationName;
   }

   private ITypeSignature fieldType;

   public override void Implement()
   {
      var newField = 
        new FieldDefDeclaration
          {
            Name = FieldName,
            Attributes = FieldAttributes.Public,
            FieldType = FieldType
          };

      ((TypeDefDeclaration) TargetType).Fields.Add(newField);

      var attribute = Utils.CreateAssociationAttribute(
        Task.Project.Module, AssociationName);
        newField.CustomAttributes.Add(attribute);
   }

   public string AssociationName { get; set; }

   public ITypeSignature FieldType
   {
      get
      {
         if (fieldType == null)
         {
            fieldType = 
              Task.Project.Module.FindType(
                FieldTypeName, 
                BindingOptions.Default);
         }
         return fieldType;
      }
   }

   public string FieldTypeName { get; set; }
   private string FieldName { get; set; }
}

The waever is an implementation of the PostSharp TypeLevelAspectWeaver and its Implement method is where the new field is created.  This method simply creates a new FieldDefDeclaration that represents the new field, sets its name, defines its visibility (by setting the Attributes property) and sets it's type.  The type is derived from a helper property called FieldType which uses PostSharp's built in Task.Project.Module to find the type of the name that was specified when we created the attribute in stage 1.
Then, the new field is simply added to the target type's fields collection.  Next, a helper method is called to create an instance of the custom attribute we want to add and is added to teh new field's custom attributes collection.  That's all there is to it!!!

PostSharp has been widely praised for having a very clean and well designed API.  After doing this I can really see why it is so well thought of - we have been sheltered from all the horrid IL generation that is usually associated with this sort of task.  Quite simply, PostSharp totally rocks and Gael Fraiteur has done an amazing job!

The Results
So, what do we have now?  If you remeber, we started with types that looked like this:

    [AllowXpoOneWayAssociations]
  public class Customer : XPObject
  {
     public XPCollection Orders { get; }
  }

  [AllowXpoOneWayAssociations]
  public class Order : XPObject
  {
  }

If we now look at the assembly in Reflector, we can see that a public field along with an custom attribute has been added to Order and an attribute has been added to Customer:





Back to XPO
So, most of the above has been about PostSharp.  Specific to XPO, the custom attribute I have added is the AssociationAttribute required by XPO to link the two sides of the association.  So, I started with a one-way association and have used PostSharp to magically turn that into a two-way one-many association.

If you want the code, you can get it from here.  Note that I've put up the XPO version and a version that doesn't require XPO.

Update: I've edited this to show that the XPCollection were the generic XPCollection 12-Nov-2008.

Monday, 27 October 2008

Using C# Automatic Properties with XPO Objects - Part 2

In part 1 we looked at how XPO implements change tracking by utilising some magic from the base XPObject class.  An XPO object looked something like this:

public class Customer: XPObject
{
  private DateTime date;
  public DateTime Date
  {
    get { return date; }
    set { SetPropertyValue("Date", ref date, value); }
  }

  [Association("CustomerOrders", typeof(Order))]
  public XPCollection<Order> Order
  { 
    get { return GetCollection<Order>("Orders"); } 
  }
}

Wanting to cut down on the syntatic noise, I'd like to be able to use C# automatic properties to make my classes to look like this:

[XpoAutomaticProperties]
public class Customer: XPObject
{
  public DateTime Date { get; set; }

  [Association("CustomerOrders", typeof(Order))]
  public XPCollection<Order> Order
 
    get; private set; 
  }
}

The secret here is the XpoAutomaticProperties attribute and the work that this does.  Applying this attribute to the class makes two things happen:
  • Changing a property value will raise the changed notification events.
  • Accessing a collection will instantiate and set up the collection.
XPO objects notify observers of changesto values using a changed event.  Collections have similar events events are fired when the collection changes or when an item in the collection changes.  Note also that the GetCollection method above sets up the collection so that it is aware of being a property of a containing object.  This will also be handled by the attribute.

Along with the XpoAutomaticProperties attribute, there is one other thing that is introduced.  The SetPropertyValue call is responsible for firing the changed event.  I will introduce to allow me to call back to an object to instruct it to notify observers of changes (XPObject has exactly such a method).  The interface looks like this:

public interface IPropertyChangedNotifier
{
  void OnChanged(
    string propertyName, 
    object oldValue, 
    object newValue);
}

Okay, if you've got this far, you must be wondering how do we actually do this?  The answer is that we use the incredible PostSharp to help us add the required code we need into our objects.  PostSharp is an aspect oriented programming (AOP) library and toolset that makes it easy to add code into your objects during compilation.  As the changes occur at compile time, you avoid the runtime performance hits that would come from using reflection.

PostSharp makes the process of generating and adding IL code to your assemblies at compile time ridiculously easy to acheive for such a complex task.  Although PostSharp allows you to drop down and weave any IL code you like into your assemblies, there is a  The PostSharp website has a number of excellent examples of how to work with PostSharp, which are extremely impressive and worth checking out.  It is also very well documented.  PostSharp is an open source library that is free even for commercial use and, incredibly, is the work of one man: Gael Fraiteur.  Everything that we do here is based on the excellent examples that Gael provides with PostSharp, so check those out when you can.

From this point on, I am going to assume that you have some knowledge of AOP and PostSharp.  So, back to the XpoAutomaticProperties attribute and how this works.  The attribute is a PostSharp attribute in which you override a base method to do the work.  The method looks like:

public override void ProvideAspects(
  object targetElement, 
  LaosReflectionAspectCollection collection)

Inside this method you use reflection to interrogate the properties of the type and then add some code to that property like this:

1 if (property.CanWrite && property.CanRead && !property.IsCollection())
2 {
3   var setMethod = property.GetSetMethod(true);
4   if (!setMethod.IsStatic)
5   {
6      var aspect = new PropertyChangedNotifierSubAspect(
                    this, property.Name);
7      collection.AddAspect(setMethod, aspect);
8   }
9 }

Remember that all this code is firing at compile time so the reflection will not affect your runtime performance!  So, in line 1 we check that the property (a PropertyInfo) is read-write and is not a collection.  We then use reflection to access the property's setter in line 3 and check that we are not looking at a static property in line 4.  In line 6 we create a new PostSharp aspect - the PropertyChangedNotifierSubAspect - and add it to the collection that PostSharp supplies.  Note that the name of the property is passed in to the aspect's constructor - this is how we avoid the use of string literals for property names.  After this, PostSharp does all the work for you.  Well, PostSharp does the IL weaving for you, there's still a little more for us to do.

The PropertyChangedNotifierSubAspect decends from the built in PostSharp type OnMethodBoundaryAspect. This allows you to easily acheive a number of things when a method is called in your code. We use two of these to change the property's setter: first we store the old value when the setter is entered, then when the setter method completes we determine if the value has changed and fire the changed event accordingly.  PostSharp elegantly provides us methods that we can override to achieve all this - we never even have to leave C# or think about IL.  This is how we store the existing value when we enter the property's setter:

1 public override void OnEntry(MethodExecutionEventArgs eventArgs)
2 {
3   base.OnEntry(eventArgs);
4   var instance = (XPBaseObject) eventArgs.Instance;
5   oldValue = instance.GetMemberValue(propertyName);
6 }



We simply override the base class method and use the data supplied argument's to access the object whose property has changed.  We cast it to be an XPBaseObject and use the GetMemberValue to access and store the value of the property on entry.  Note here that the GetMemberValue is supplied by Developer Express and is performance efficient (itself using generated IL to access the property value).  If you are using XPO with your own objects that do not subclass the built in XPO types then you will have to use reflection or some other means to access the entry value.  Note also that this code is executes at runtime.

In a similar manner, we then override the OnSuccess method to execute code when the method successfully completes (i.e. exiting with no unhandled exceptions).  At this stage, we compare the current value with the existing and fire the changed event if needed.  The code looks like: 

1 public override void OnSuccess(MethodExecutionEventArgs eventArgs)
2 {
3    if (!(eventArgs.Instance is IPropertyChangedNotifier)) return;
4    var newValue = eventArgs.GetReadOnlyArgumentArray()[0];
5    if (ValuesEqual(oldValue, newValue)) return;
  
6    var instance = (IPropertyChangedNotifier) eventArgs.Instance;
7    instance.OnChanged(propertyName, oldValue, newValue);
8 }

 Again, PostSharp supplies us with event args that allow easy access to values.  We also use our IPropertyChangedNotifier interface to do the notification.  In line 4 we access the new property value from the event arguments supplied by PostSharp (again, no reflection needed!) then call a method to check for changes in line 5.  If we have a change to the property, we instruct the object to notify the world of the change in lines 6 and 7. 

Okay, so where are we now?  We've used PostSharp to create a special attribute.  We've applied the attribute to the classes in which we want to use automatic properties.  PostSharp recognises our attribute and injects code into our assemblies at compile time.  The code that is injected is defined by us in classes that we create from buit in PostSharp types.  These types are called aspects and we used the one that allows us to modify a method - specifically, the property's setter method.  To modify the method was pretty easy - we just override a couple of methods and use the information that PostSharp passes back to us to do what we want.

PostShapr also allows you to work with fields and add code to when the fields are accessed.  The way I initialise collections use this feature of PostSharp, but I'd suggest you head for the PostSharp site to learn more of what you can do with PostSharp.

Before we leave this, there's one gotcha to be aware of: the release version of PostSharp, 1.0, does not play well in partial trust scenarios.  If this is important to you then you'll be pleased to know that the next release 1.5 addresses this and version 1.5 is in CTP2 stage at time of writing.

If you want more, then you can get the code from here.

Sunday, 26 October 2008

Using C# Automatic Properties with XPO Objects - Part 1

In my previous post I touched on the fact that objects in Express Persistent Objects (XPO) support change tracking. One area that this is used by their Unit of Work to track the changes made to objects. Another use is when data binding objects to a UI. So, how do you enable change tracking in your object model using XPO?

XPO supports a variety of methods for achieving this, but the easiest is to inherit your domain objects from XPObject. When you do this change tracking is enabled by calling a magic setter method in your property setters and using their built-in collection type for association properties:

public class Customer: XPObject
{
  private DateTime date;
  public DateTime Date
  {
    get { return date; }
    set
    {
      SetPropertyValue("Date", ref date, value);
    }
  }
  [Association("CustomerOrders", typeof(Order))]
  public XPCollection<Order> Orders
  {
    get { return GetCollection<Order>("Orders"); }
  }
}

Note that Association attribute on the collection property is required by XPO and indicates that the property is one end of a two-way association - either one-many or many-many. Associations are always two-way, except one-one associations which are handled differently. So, for completeness, with the example above being a one-many relationship, you will need the following to express the other end:

public class Order: XPObject
{
  private Customer customer;
  [Association("CustomerOrders")]
  public Customer Customer
  {
    get { return customer; }
    set 
    { 
      SetPropertyValue("Customer", ref customer, value); 
    }
  }  
}

It makes sense to use a collection type that supports change notification and the calls to SetPropertyValue are a fairly elegant way to notify change. Okay, this is all good, but I like to cut down the syntactic noise as far as possible. This basically means that I want to to use C# automatic properties (and I also don't want get into using design time code generation techniques to help me out). So, where do we go from here? We go to this:

[XpoAutomaticProperties]
public class Customer: XPObject
{
  public DateTime Date { get; set; }
  [Association("CustomerOrders", typeof(Order))] 
  public XPCollection<Order> Orders 
  { 
    get; private set; 
  }
}
[XpoAutomaticProperties]
public class Order: XPObject
{
  [Association("CustomerOrders")] 
  public Customer Customer 
  { 
    get; private set; 
  }
}

The classes above will give the same functionality - change tracking and collection creation - as the previous examples. Except, there is much less code to read, just automatic properties and an extra attribute on the class declaration. Take a look at part 2 to see how this can be done.

Friday, 24 October 2008

ORM with Developer Express Persistent Objects (XPO)

I've been using ORMs for a long while now and love the speed and flexibility they can bring to the development process. For projects in  work we use an ORM that we wrote ourselves.  As I'm now doing some projects outside of my day job, I have been looking around at the available ORM offerings for a few months now.  I'm now pretty likely to be using Express Persistent Objects (XPO) from Developer Express - a developer tool vendor with an excellent reputation and strong background.

I've been evaluating their UI controls for a while now and I have been generally very impressed with both their products and their excellent support.  XPO comes from this background and has the main features that I want:

  • Support for the Compact Framework.
  • A LINQ provider.
  • Generation of schema from object definitions (you can also generate objects from an existing schema).
  • Wide support for a variety of databases (including my target database, VistaDB). 
  • Easy data binding of objects to controls (as you'd expect from DevExpress!).

It does have a few quirks that I'm a little unsure about at the moment.  The main ones for me now are:
  • All associations with multiplicity greater than one have to be two-way.
  • The automatic schema generation mechanism will not widen string fields in existing schemas. 
I also get the feeling from reading their forums that XPO gets a "little less love" than some of their other products.  I think that it may be seen as either largely functionally complete, or that it now plays a supporting role to their application framework, XAF.

However, these are only small niggles and the product is seems to be well constructed, uses best practices, has good support from a much respected tool vendor and is realistically priced.  If you are coming to ORM from a data-driven background, then you will probably even be comfortable with having to always having to have have two sides to an association!  It is worth noting that XPO takes care of the other end of the relationship for you - if I add an order to a customer, then the order's customer is automatically set...neat and sweet!

If you are looking for an easy to use commercial ORM that is reasonably priced, then I would recommend you take a look.   If you are not looking for a non-commercial ORM, or want to learn about the world of object-relational mapping, then head off to NHibernate.

Edit: Just thought it worth noting that the "small niggles" about XPO are in the context of my current project, which has a relatively simple object model - one for which I would happily manually write the data access code.  I would not be comfortable recommending XPO for complex object models at this stage.

Thursday, 26 June 2008

Praise: Subversion Hosting at Wush.net

I've recently signed up for Subversion hosting with Wush. I spent a long time looking at various online providers before deciding on Wush. I am more than happy with my choice!

I currently have a no-frills service with a gigabyte of space with unlimited users across a single Subversion repository for $20USD per quarter at time of writing. (You can add extra Subversion repositories for $5USD.)

Hey, I don't want frills, I want service and Wush have given me absolutely top class service! Their service started when I was asking initial questions and has continued through my teething problems (like not remembering how to set up other users; how to integrate with FogBugz, etc.).

There are a lot of good looking offerings out there with some very slick interfaces. However, these often took, literally, days to respond to my support requests. Sorry - not good enough!!

Wush does not have a slick interface but has a strong, consistent and solid level of support from the start.

When a job's done right, you have to say so: Wush have to be one of the best out there and I wholeheartedly recommend them!

Tuesday, 24 June 2008

ECO VistaDB Provider on CodePlex

I've put the code for the ECO VistaDB Provider up on CodePlex. Get if from:
http://www.codeplex.com/ecovistadbprovider
I'd be very interested to hear of any experiences if you use it!

Sunday, 22 June 2008

Flintstone Machine: Enterprise Integration Pattern

In the Flintstones cartoon, the "modern stone age" families used used machines that were functionally equivalent to the contemporary household utility appliances, but were powered by animals inside. For example, in the recent film, their garbage collector chute leads to a pig in the cupboard that eats all the waste food.

In enterprise IT systems we find similar things: systems that hand off work to a human worker when that work could be accomplished by the system or passed to another system. The worker becomes the equivalent of the animals inside the Flintstones' machines.

The key feature is that the task the worker performs could be done, in whole or in part by software; indicating areas where greater operational efficiencies may be achieved. Of course, it does not indicate that there is a cost benefit to making the change!

This can make sense as a temporary step on the journey toward greater integration. To keep your promises, you might roll out your online ordering system to the world and start taking orders today, before you can bring the warehousing system to the party. You have a team of people working like hell to take the orders to the warehouse and update the stock levels. The warehousing integration rolls out later.

The enterprise system is like a swan, the surface is all graceful and efficient, while the legs are working like hell to move things along!

Also see: Swivel Chair Integration

Thursday, 19 June 2008

UAC: Peace at Last

Caveat: do not try this at home unless you understand and are willing to accept the reduced security. Read the comments in the link below for more details.
That said, I've found some valium for the soul! The howtogeek.com article shows how to automatically elevate for the admin accounts on my machine. I've set this up and have just gone to delete some bin and obj folders as I did last night. However, tonight I feel positively warm and glowing - it simply asked me to confirm the deletion and then they disappear.

Bliss!

UAC: Your Time is Marked!

Before zipping the source for the last post, I went to remove the bin and obj folders. These are located in my documents folder (under the VS2008 projects folder). My login has admin rights to the machine and I'm not on any domain either - just a standalone home machine!

Life should be sweet then? Well, not if you're using Windows Vista with UAC enabled. There are seeming endless requests for permission to continue. It's a click multiplier...the more you want to do, the more you have to click!

I began by thinking that it's all worth while, it's for security reasons, etc. etc. Right now I'm at the end of my tether and am about to turn it off.

One of my favourites is that when trying to delete the bin/obj folders, I can't! I just get the following:



I created these folders, inside my user profile, on my machine, upon which I have full administrative rights. There were no files locked by other processes (merci, Cedrick!). I had only created the folders a few minutes previously. Man, this is the most tedious version of Windows I have ever used. This stuff drives me insane!

Sometimes when I get the dialog above, if I go into the folder and delete files and subfolders before I delete the main folder, I get to delete the main folder after all that. Wow, that's great, there's a workaround! Well, no - it doesn't always work, just sometimes!!

Vista UAC - your time is marked!

Wednesday, 18 June 2008

Implementing ECO on VistaDB: part 2

To continue my earlier post, I now have got ECO to write and read from a VistaDB database. I had a few tweaks to make to the source I posted earlier against the ECO newsgroup. But, it's looking very good so far.

The source code can be got from the newsgroup.

Enjoy!

The generated table seen from VistaDB:



A data grid bound to the ECO datasource:

Tuesday, 17 June 2008

Implementing ECO on VistaDB

I was doing an evaluation of ECO over the weekend and I needed to see if I could wire it up with an embeddable database.

Sure, they already had support for SQLLite, Firebird and others. I wanted to be able to connect to VistaDB. Whilst this was not supported out of the box, a couple of hours tweaking, getting support from their newsgroup and reading the manual (after being reminded!), I have got as far as generating a schema on VistaDB from ECO.

This is a real compliment to a framework as advanced as ECO that a new user can do this after a few hours of work. Sure, I am familiar with the concepts of ORMs in general and have a few weeks worth of experience of ECO from 5 years ago. But, hey - I'm no rocket scientist and this is the first time I've worked with VistaDB - a compliment too for the good work in VistaDB, there were no surprises, it all just worked!

Still there's much more to do, this very much a work-in-progress. Will keep you posted!

Update: you can get the work-in-progress source here, if you're interested.

VistaDB - It Just Works!

I'm looking for an database for a Dotnet 3.5 winforms application that I will be making available for a mass audience. The application will install on the users machine and be hold its data on that machine.

I want minimise the problems for my users. I do not want any other software being able to affect my software. The worst case scenario I want for support is to uninstall and reinstall the application, possibly the Dotnet Framework.

This means I want to embed the database in the application. I do not want to rely on other vendors sharing an installation of MS SQL Express or similar. I want it all to myself!
Publish Post
I love Firebird from my Delphi days and SQLLite is hot as hell, but enter the newcomer: VistaDB.

Fully managed, CLR compliant and written in managed C#, this little puppy is easily my DB of choice for this work. Supports large DBs, no arbitrary limits on anything, goes to the web, desktop or mobile. easy integration with Visual Studio, comes with its own management suite, and a whole host of other goodies. This will cost not much more than a half decent management suite for Firebird or SQLLite!

Although it's not pertinent for me in the current project, this database is capable of being completely embedded in an ASP.Net web page and saving you loads of cash on your hosting - the excellent and free MS SQL Express costs to host, as does the also excellent and free MySQL. VistaDB is a file and an assembly...can it get simpler?

Check it out here

ECO - Heavy Lifting Support

I have developed in Borland Delphi since the 16 bit version 1 and shipped apps for Windows 3.1. In early 2001 I was working for a forward thinking UK based digital TV/media-on-demand company. Our primary product was highly scalable, highly distributed, bleeding edge performance media server. Sadly, the technology was lost as the company was a tech startup and funding dried up...the world was not ready for video over DSL then. If only, eh?

Anyway, these guys were code generating most of their code from UML (Rational Rose at the time) into C++ and building for Solaris and Linux. The closest I got to this was to write a build tool that QA could use to kick off the main product's build on Linux along with the Windows apps' build...the only bit of Kylix programming I ever did. (Never met anyone else who did much more either!)

I was responsible for the design and development of our Windows based management applications and, inspired by the code generation techniques used by the rest of the gang, was implementing an ORM to speed up the development of the end-user apps. Nobody used the term "ORM" in those days (at least, as I remember). It was MDA back then, before the OMG trademarked the term (yep, we all had to adopt a new vocabulary because of that!!).

It was then I discovered Bold for Delphi - a fully featured object-to-relational framework, with all the trimmings: integration into Rational Rose. object versioning, caching and concurrency support to name but a few features. Man, this was 2001, for god's sake...where did you find features like that in the Window's world?

Very soon after, the company I was working for went down due to funding being withdrawn and I have left Delphi behind for Dotnet. After five years in the Microsoft arena, I am shopping for an ORM to support a new app dev for a new client. Guess what...

Bold are still going, the company is now called Capable Objects and the product is called ECO. It's still true to its original roots, is still supremely capable (just like they say on the tin!) and has been released for Visual Studio!

I've been looking around for something to help in a new project for a potential mass market application, that will be deployed on client's machines. This is one of my tools of choice for the new endevour.

If you haven't had a look, check out the fully functional version from here.

Hello World!

Welcome to my first blog post. I hope to be sharing some of my rambling thoughts on software, its development, procurement, use and abuse.

I've been in the development industry since 1997 and will hopefully be so for much longer.

My primary focus is end user business applications - their development, use and abuse; business integration scenarios and the lifecycle management of software in the business.

I hope to be blogging some of my thoughts in these areas in the coming months.

Stay tuned!