Hi all!
I bought C# Business Objects 2005 in december in preparation for a new project. I've been using some of the concepts in the book and I recently downloaded the latest version of CSLA.
Our product uses metadata heavily and I see the csla v3.5.x has a way of adding metadata to your BO's properties. This wasn't in the framework when I first looked at CSLA so I "rolled my own".
First I have to say that I'm not crazy about the concept of managing property values but I do like supporting metadata at the BO level (as opposed to letting the UI domain manage this).
I'd like to share my approach with you because I'm curios as to the possible benefits of CSLA's approach vrs "my own".
I chose to use attributes, something like the following:
class FieldMetaData
{
// backing fields, setters/getters left out
public string FieldName;
public string DisplayLabel;
public string ReportLabel;
public bool IsRequired;
public bool IsVisible;
public string Storage; // e.g. TableName.ColumnName
}
class MetaDataAttibute: Attribute
{
// backing fields, setters/getters left out
public FieldMetaData MetaData;
}
class TestBO
{
[MetaData(RegisterFieldMetadata("Data"))]
public string Data;
}
public string Storage; // e.g. TableName.ColumnName
}
You get the picture... I've looked at CSLA's PropertyMetadataManager class an how it's used by BusinessBase. Why use a static field instead of attributes? FYI, our metadata can change at runtime and it includes a lot more that is shown in this example.
I look forward to your thought and comments.
Ultimately I had exactly two goals for this design:
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.
I see the benefits of using static fields to hold metadata (I like the WPF pattern as well).
What eludes me is how to make the metadata available to databinding mechanisms with out the use of attributes and reflection. CSLA must do it somehow because I see the project tracker example shows friendly names for bo properties. I'll take a deeper look and see how it's done.
I'm working on some interesting technologies for our product (a POS system currently written in Delphi). As we think of ways to migrate our app to .NET I'm having to takle problems not commonly solved using business objects (e.g. metadata and datamodels that can change in a production environment).
I look forward to sharing (what I'm allowed to) with the group.
Copyright (c) Marimer LLC