Monday, March 03, 2008
« CSLA .NET 3.5 property code reduction | Main | Consolidated blog feed for Microsoft Reg... »

Another place where I was able to reduce business object code in CSLA .NET 3.5 was to effectively eliminate the GetIdValue() method.

Prior to version 3.5, GetIdValue() was required, and you had to provide a unique value identifying your object. This value was used to implement Equals() and GetHashCode(), and was used as the ToString() value. This was good, because it enabled the concept of logical equality, where objects were equal to each other based on their id value.

For better or worse, WPF doesn't support logical equality. They only support absolute equality - ideally implemented by comparing all properties of the two objects so two objects are only equal if all their properties are equal. A poor man's replacement is to use reference equality - which is much faster but is technically less accurate. The effective default in .NET is reference equality.

CSLA .NET 3.5 no longer overrides Equals() or GetHashCode(), so it now uses the .NET default behavior. This makes WPF happy. This might break some people's existing code (though a poll on the forum indicates it is a non-issue for virtually everyone), because there is no longer any idea of logical equality unless you implement it yourself.

The upside though, is that you no longer need to override GetIdValue(). I left the method in the framework for backward compatibilty, so if you do override it your code will continue to compile (though the value is now only used in a ToString() override).


Monday, March 03, 2008 11:39:27 AM (Central Standard Time, UTC-06:00)
Rocky -

I do not get why this would not be a big deal with a different UI on top of the business objects. The Contains method for example would return a false within a collection if the primary keys are the same but the other properties contain different values. I see this as a potentially big change to the behavior in the business logic. Would we just have to keep overriding the GetIdValue() method in these cases?
Monday, March 03, 2008 11:47:19 AM (Central Standard Time, UTC-06:00)
Yes, Contains() calls Equals(). And you have touched on the one area where a few people might feel some pain due to the switch from logical equality to absolute equality.

But this isn't as bad as it seems, because I'm simply reverting to the default .NET behavior. If normal .NET collections/lists work for you now, then this new model will work for you too - by definition.

However, if your app really does require logical equality, then you'll need to override Equals() and GetHashCode() yourself - much like I did in CSLA prior to 3.5. And you'll have to realize that this breaks WPF - so you can't have the logical equality behavior and use WPF/Silverlight at the same time.

Since most people don't really care about logical equality, but will care about being able to use WPF/Silverlight (they are the future of all UI technologies after all), I thought it was important to make this change earlier than later.
Wednesday, March 05, 2008 9:32:22 PM (Central Standard Time, UTC-06:00)
2+ thumbs up for this change! Most (well, depending on what you are doing) of the time (especially if you are doing searches) you only want or need to store in a dictionary keyed by the default object reference implementation of Equals/GetHashCode - overriding Equals/GetHashCode takes away this as an option and presupposes a style of coding (not to mention those entities that don't have a key value yet...). For those times when you want to key on primary key just use a dictionary where Key is your entity key and Value is your entity. However, a common way to get an entities key would be useful for library functions.
Matthew Hobbs
Comments are closed.