I was wondering if anyone has a good implementation of dynamic or runtime properties in CSLA business objects? I found a few threads related to the issue but nothing definitive.
The reason I ask is that we often have to tie into existing databases that have userdefined fields. This is easy when there is a set number of udfs, we just add a possible udfs as normal properties. But we have come across applications/databases that support infinite udfs (often called UET's or user extended tables). This presents more of a challenge as the schema we are working with can essentially be infinately variable.
In the past we have just built a "Property/Properties" class/collection that have fields like PropertyName,Value, DataType; then exposed proper views of this data through a custom TypeDescriptionProvider
A Properties collection has a child property object with the following values:
PropertyName = "udf_myproperty"
Value = "Scott"
DataType = System.String
The properties collection is added to the standard object with normal field schema. Say the normal class has an ID property and a Name property. Reflection would return ID, Name, and Properties (collection) from the GetProperties call. Therefore we use the TypeDescriptionProvider to allow for a custom GetProperties implementation that bubbles up the dynamic properties from the Properties collection and ignores the Properties collection object. Once the provider is added, a call to Typedescriptor.getproperties will return ID, Name, and udf_myproperty.
I know that much of CSLA uses reflection to find properties in may occassions to do binding and the like. Has anyone done similar work using TypeDescriptors instead of reflection?? Am I even on the right track with this thinking, maybe someone else has a more elegant solution?? I am pretty new to CSLA so maybe I am overlooking a feature??
I haven't fully explored this, and so may not be totally correct. However, I don't think there's any major issue using ICustomTypeDescriptor with CSLA.
CSLA itself doesn't use reflection to do data binding. Data binding uses reflection to do data binding But data binding first checks for ICustomTypeDescriptor before doing its binding - this is how data binding works with the DataTable for example.
The rule methods in CommonRules do use reflection, and so you couldn't use them. But they are relatively easy to re-implement in a manner that would work with ICTD I would think.
The validation and authoriziation subsystems are string-driven. I think you could make appropriate CanReadProperty(), CanWriteProperty() and PropertyHasChanged() calls in your getproperty and setproperty methods, because those methods clearly have the dynamic name of the property available for their use.
Thank you for the quick response. I am glad to find out that normal databinding uses the ICTD, you learn something new everyday . I can see where reimplementing the rules would be pretty simple. Of course, I would have to provide a mechanism to add these rules at run-time.... Has anyone in the community attempted to do this???
I am also interested in your opinion of this implementation of dynamic custom properties. Is this a good approach or is there something out there they may be more elegant??
Thanks again for your help,
Yeah, adding the rules at runtime is a requirement for this. The only trick to it is creating the delegate pointer from a string, which requires a bit of reflection. It helps too if you make your rule implementations run off DecoratedRuleArgs so you can easily pass in name/value parameter pairs.
Of course that leads to the requirement that you have the rule metadata (rule name, property name, parameter name/values) available
Copyright (c) Marimer LLC