I have a business object that implements a property whose valid values are only those coming from a list of approved values. The values contained in the list come from a database table.
In order to prevent the user from setting the property to an invalid value, I have created a validation rule that verifies that the value entered into this property is contained on the list.
So in order to handle this gracefully, my business object does two things:
1. Retrieves and stores the list of these valid values (I need to do this so that my validation rule has the list to check against).
2. It also goes one step further and actually exposes the list of valid values as a property on my object so my UI can implement a combobox that binds its ItemSource property to it to allow the user to easily select a valid value.
Is this a good way to handle this scenario?
What is the UI framework you are using?
Yes, in general this is a good solution.
However - having the list of "allowed properties" in the BO is not always that good - especially in Windows Forms databinding and if your object is contained in a list.
The other issue with having the list of allowed values as a property of your editable object, is that when you save the editable object, that list of allowed values will serialize to the server too. That's probably wasted bandwidth, because the server could probably re-retrieve the values cheaper than the cost of serialization.
So you might want to implement this as a lazy-loaded property, with a private backing field, and mark the private backing field as NotSerialized. That will prevent the value from serializing over the wire, and any access of the property would trigger loading of the list. This doesn't work well in Silverlight, because the lazy load is async, and that complicates your scenario quite a lot.
I would encapsulate the list in a read only collection, caching the list in a static variable. This allows you to use it both for drop down population, and within your business rules.
There are, generally speaking, two types of lookup list though.
There's the global lookup list, where a single list is used by many instances of another type to do the lookups or validation. That can be cached in a static cache field as you suggest.
There are also instance-specific lookup lists, where the lookup list is unique to a specific instance of the editable business object. Such a lookup list can't really be cached in a static field, because it is unique to that one editable object instance.
A UoW object can be used to retrieve such a thing, or a nonserialized lazy-loaded property can work (but not in Silverlight).
To be honest I hardly ever use the static property pattern for implementing this. I use the MS Enterprise Frameworks caching functionality, and have created a base read-only list that takes advantage of it. Based on the factory methods input criteria, I generate a key that can be used to access the cached data, or if not found, pass the criteria on to the data portal. In this way I have the granularity required for individual business objects to have their own lists of values, while getting the advantages of cached data. There are additional benefits in having the ability to age the data, so it can be re-retrieved periodically if the app is open for a prolonged period of time.
Copyright (c) Marimer LLC