Ultimately I had exactly two goals for this design:
- I knew Silverlight was coming, and I needed a way to do low-trust serialization of object data, which means managed backing fields, which means some way to describe your properties.
- I wanted to eliminate the use of string literals throughout the code (when calling CanReadProperty(), CanWriteProperty(), CheckRules(), PropertyHasChanged(), GetProperty(), SetProperty(), ReadProperty() and LoadProperty()) because string literals reduce maintainability. This is the reason for the static fields - they act as a token for the property and avoid propogation of string literals through business classes.
If you look back in time, there's a thread discussing the design a few months ago. The design was refined and enhanced based on feedback from several people, some who'd done similar things to me and you. But ultimately I was after the two goals I listed, and the other changes were nice improvements while still achieving those goals.
Whether you use managed backing fields or private backing fields is up to you. The concept of managed backing fields exists primarily to support Silverlight, and possibly other medium or low trust scenarios in the future. .NET serialization of non-public fields requires a lot of trust, and managed backing fields exist so CSLA can serialize your object's data without the need for reflection or elevated trust.
In terms of how you mark your metadata, attributes are fine if you read and cache them. But one of the slowest reflection operations is retrieving custom attributes, so you really need to be careful how you use them.
I think it would be possible to define attributes for the CSLA model too, but the result would be the same (some code would reflect over your type and would do a RegisterProperty() based on the attribute values - the results being cached in static fields like they are now.
With CSLA I chose to (generally) follow the pattern Microsoft has set forth with dependency properties in WPF and WF, partially to avoid adding more concepts to the mix. Microsoft already defined the concept, I'm just adapting it to my needs.
CSLA doesn't (at least not easily) support changing the metadata at runtime. The PropertyInfo<T> objects are cached on a per-type basis for performance and memory reasons. However, you can extend PropertyInfo<T>, and could devise a mechanism by which your additional metadata could be more dynamic. The core metadata defined in PropertyInfo<T> can't be dynamic - specifically the property name - because that can't change without a recompile.
Rocky