tags:

views:

164

answers:

2

We have lots of immutable value objects in our domain model, one example of this is a position, defined by a latitude, longitude & height.

/// <remarks>When I grow up I want to be an F# record.</remarks>
public class Position
{
    public double Latitude
    {
        get;
        private set;
    }

    // snip

    public Position(double latitude, double longitude, double height)
    {
        Latitude = latitude;
        // snip
    }
}

The obvious way to allow editing of a position is to build a ViewModel which has getters and setters, as well as a ToPosition() method to extract the validated immutable position instance. While this solution would be ok, it would result in a lot of duplicated code, especially XAML.

The value objects in question consist of between three and five properties which are usually some variant of X, Y, Z & some auxiliary stuff. Given this, I had considered creating three ViewModels to handle the various possibilities, where each ViewModel would need to expose properties for the value of each property as well as a description to display for each label (eg. "Latitude").

Going further, it seems like I could simplify it to one general ViewModel that can deal with N properties and hook everything up using reflection. Something like a property grid, but for immutable objects. One issue with a property grid is that I want to be able to change the look so I can have labels and textboxes such as:

Latitude:   [      32 ]  <- TextBox
Longitude:  [     115 ]
Height:     [      12 ]

Or put it in a DataGrid such as:

Latitude  |  Longitude  |  Height
      32           115         12

So my question is:

Can you think of an elegant way to solve this problem? Are there any libraries that do this or articles about something similar?

I'm mainly looking for:

  • Code duplication to be minimized
  • Easy to add new value object types
  • Possible to extend with some kind of validation
A: 

Can you think of an elegant way to solve this problem?

Honestly, you just dance around the problem, but don't mention the problem itself ;).

If I correctly guess your problem, then the combination of MultiBinding and IMultiValueConverter should do the trick.

HTH.

P.S. BTW, you have immutable class instances, not value objects. With value objects (which are described by struct keyword) you would dance much more no matter if there were setters or not :).

archimed7592
I think you have a misunderstanding of value objects. Value types are structs as you say, but a value object isn't the same thing.See this article for more information: http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/05/20/entities-value-objects-aggregates-and-roots.aspx
Jacob Stanley
Could you perhaps elaborate on how can I make the problem more clear?In a nutshell, I have an object which is immutable, and I'd like to be able to easily bind textboxes to its properties in the same way I can with a mutable object.
Jacob Stanley
Sorry about value objects - my fault, didn't know there is one.About elaborating the problem - for example you can provide one of snips which you want to generify. Maybe, it would also be useful if you provide some meta-snips of your seeing of the ideal generic solution in XAML.
archimed7592
+1  A: 

Custom Type Descriptors could be used to solve this problem. Before you bind to a Position, your type descriptor could kick in, and provide get and set methods to temporarily build the values. When the changes are committed, it could build the immutable object.

It might look something like this:

DataContext = new Mutable(position, 
    dictionary => new Position(dictionary["lattitude"], ...)
);

Your bindings can still look like this:

<TextBox Text="{Binding Path=Lattitude}" />

Because the Mutable object will 'pretend' to have properties like Lattitude thanks to its TypeDescriptor.

Alternatively you might use a converter in your bindings and come up with some kind of convention.

Your Mutable class would take the current immutable object, and a Func<IDictionary, object> that allows you to create the new immutable object once editing completes. Your Mutable class would make use of the type descriptor, which would create PropertyDescriptors that create the new immutable object upon being set.

For an example of how to use type descriptors, see here:

http://www.paulstovell.com/editable-object-adapter

Edit: if you want to limit how often your immutable objects are created, you might also look at BindingGroups and IEditableObject, which your Mutable can also implement.

Paul Stovell