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.