Custom PropertyInfo with mutable values?

Custom PropertyInfo with mutable values?

Old forum URL: forums.lhotka.net/forums/t/10082.aspx


hurcane posted on Wednesday, February 16, 2011

We have a WinForms project using CSLA 3.0.5 and are finally able to consider supporting technology beyond .NET Framework 2.0. I have been reading about 3.8 (do not have the 2008 book yet) and also 4.0. The idea of managed fields and eliminating string-based property references is very appealing, but we have some roll-your-own customizations that won't work with managed fields.

Properties are exposed as string, boolean, etc. Internally, the values are passed to custom classes (CSLA-based) for each data type (StringField, IntegerField, etc.). With managed fields, I do not think we can use these "Field" classes.

The field classes are holding original and current values, and have additional properties such as IsRequired, IsReadOnly, MaxLength (for string), Min/Max values (for integers and doubles) and scale/precision values.

IsDirty is overridden to compare old and new values. I have seen how other people have implemented that with managed fields by subclassing PropertyInfo<T>.

These "Field" classes are also exposed through dictionaries and used by custom controls. The custom controls get the appropriate "Field" classes when the datasource changes. The "Field" class is used to configure the control's behavior, such as disabling the control for read-only properties, showing an indicator for required fields, etc.

I think we can subclass PropertyInfo<T> and FieldInfo<T> to include some of the metadata properties that are not already included. However, the values of these properties are mutable and can change at runtime. For example, when a customer ID is entered on an order entry screen, customer-specific settings may dictate that the shipping method is set to a certain default and cannot be overridden, or they may require that a PO number be entered on the order, or the total order value should be represented in 4 decimals vs 2 decimals.

Because our custom "Field" classes are based on CSLA, the custom controls can observe the PropertyChanged event and update their behavior. This does not appear possible with PropertyInfo or FieldInfo.

One idea I had is to define an event that provides an updated PropertyInfo<T> object. All custom controls would handle that event and respond only if the property name matched.

I am interested in ideas from people who may have tackled this issue already. What might be a good way to push out changes to the controls?

JonnyBee replied on Thursday, February 17, 2011

No, you should use PropertyInfo objects for this funtionality. The PropertyInfo objects is a static registered list for all instances of an object type.

I'd rather look at encapsulation this by using more of the "standard" methods in BO's toslave the UI like:

CanExecuteMethod
CanReadProperty
CanWriteProperty

And use custom rules that cehcks the metadata and property values.

This would enable you to use Csla.Windows.ReadWriteAuthorization and Csla.Xaml.PropertyStatus controls in your WinForm/WPF/SL app.

 

hurcane replied on Thursday, February 17, 2011

Thanks, JonnyBee. I presume you meant that we should not use PropertyInfo objects for this purpose. I will continue to look for other alternatives. The CanReadProperty method and authorization rules can take care of the read-only state.

It looks like my core problem is that we have rolled up value state with other metadata. We can move value state into the managed property technique, yet still maintain our other metadata as we are currently doing.

I think I may have also been confused by only skimming Jason Bock's article about implementing a smarter IsDirty method. I skimmed over the reference to IPropertyInfoFactory and translated it into IPropertyInfo. Now that I have read his article, I realize he is talking about changing internal behavior by using customized FieldData<T> classes. Those are private, so would not be useful for exposing metadata to the UI.

RockfordLhotka replied on Thursday, February 17, 2011

The property info object contains metadata for the property definition or declaration. It can't store per-instance data.

The field info object contains (at a minimum) the field value for a managed backing field. However, you can extend it to contain other metadata or data.

The field info object is available to your object through the FieldManager.GetFieldData method. This means you can expose the metadata from a field data object out through your business object if you desire.

To do that I would recommend creating a custom base class that implements some standard mechanism by which external code can ask a business object for that metadata - probably some interface that your base class (and therefore all business objects) would implement.

RockfordLhotka replied on Thursday, February 17, 2011

I should point out that this scenario is "supported" in that I envisioned this being done, but to my knowledge no-one has implemented such a solution.

When Jason implemented the alternate IsDirty behavior that was the same thing: envisioned but not implemented. He did find a couple oversights in the CSLA codebase that I had to fix to enable the scenario.

You might find the same thing, but it probably helps to know that this should be possible, so if it isn't, that's a bug.

Copyright (c) Marimer LLC