Anything wrong with using Attributes at business object level to suggest display format at UI level?

Anything wrong with using Attributes at business object level to suggest display format at UI level?

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


JCardina posted on Tuesday, May 16, 2006

I'm considering putting attributes in read only collection object fields to indicate how they should be displayed.

I'm about to port a winform csla app to web and before I start I'm "refactoring" the winform ui app as much as possible to make for less coding in the web app applying the lessons I learned from the winform app.

One of the things that kind of spiraled out of control was the number of almost identical forms for displaying read only collections in a grid.

I just kept copying a form and modifying it to display the individual fields appropriately in the grid for the particular business object in question.

I'm considering consolidating all those forms into one or as few as possible and started by looking at what is uniquely different for each form and the majority of that is controlling the display format for columns in the grid. 

I.E. on one grid I might have several decimal values but one represents a quantity another represents currency etc.  Or fields that I want to substitute my custom NameValueCellButton in where a user sees a button with text but when clicked returns the underlying GUID value for the record, that kind of thing.

Anyway, the point of this is I'm considering adding attributes instead to the fields in the read only collection object that indicate how it should be displayed so that, through reflection I can dynamically setup the columns on the fly without hard coding it.  I know this is technically putting UI info in the business object layer, but on the other hand it isn't, it's more about refining what the data actually is.  I.E. I might have a "Currency" attribute and a "Quantity" attribute both used on a decimal field value.

Or in other cases I have a string column that should display in the color set in the ARGB column so I would have an attribute indicating that it should be colored and which field contains the color.

So technically it's not UI platform specific, and not mandatory, just useful for both web and winform UI. 

Probably also attributes for columns that should be hidden always etc etc.

It seems like a good idea right now but I'm just wondering if anyone has done this or has any thoughts on the concept of putting that kind of info at the business object layer level.

DavidDilworth replied on Wednesday, May 17, 2006

This sounds like an interesting idea.  Generally I'm in favour of attribute and reflective-based programming so the idea has some merit.

I've previously used attributes this way to indicate the validation required for a given property, which we reflected out to our WebForms app to provide us with standard JavaScript validation on the most common controls (i.e. text and number controls).  This gave us string length and number limit style validation in the UI for the standard controls.

And if you already have a WinForms model of how you want the application to work, then you should have a pretty good of the model for the UI framework you need.

But if the aim is to try and have a single page for all ReadOnly Collection classes to avoid the cut-and-paste and proliferation of forms then give it a go.

The downside you're paying is obviously going to be performance due to the reflection on your BOs and the extra code you'll need in your "default empty form" to build the data grid and data binding code manually.

Just as a final thought, you might want to consider using an Interface to define the requirements for your UI page.  That way you can program your page against the abstraction defined by the Interface.  And only the classes you want to work this way should implement it.

Bayu replied on Wednesday, May 17, 2006

Hi,

I have been thinking about this as well for exactly the same reason.

I think you (we) are in fact putting UI stuff in those attributes, but that's more a question of philosophy. Let's look at the pragmatic side: it will benefit you (us) greatly, so let's just do it. Smile [:)]

Assuming we do .... I can see one major headache that will hit us sooner or later: when you want to alter your display of the data, you will modify the values of these attributes, next you will have to recompile the business objects and then you will have to re-deploy those to both clients and servers. In my experience, customers always keep requesting UI enhancements, so this scenario will unfold some time for sure.

So I would prefer to somehow put the display-related attributes outside the business objects for the aforementioned reason. I have been thinking about putting all this information in the database. For any object you could store view-related information in the DB. Then, you could also share this info between webclients and winclients or you could have different configurations for different types of clients. You could even factor in a concept of 'theming' or perhaps even user-specific or permission-based view configurations. The options are endless.

But: this will yield a another potential point of failure: clients will not be able to render themselves until they connected to the DB. They require the DB to tell them how to render stuff. This may be OK, since your client also requires a DB to have any renderable data in the first place. However, you may want to consider this scenario carefully.

I have chosen to store all display information in the DB instead of in attributes. Saves me HUGE time, all I need to do is administer these records in the DB and ALL clients will pick it up on-the-fly, no need for recompilations and/or redeployment. In addition I store some defaults in the app.config, just in case the DB is unreachable and I still need to show some stuff.

Another benefit that I found out when using this approach is that your view-related configuration is not tied directly to particular objects or properties of those objects, there is some freedom in there.

Good luck!
Bayu


JCardina replied on Wednesday, May 17, 2006

Bayu:
Hi,

Assuming we do .... I can see one major headache that will hit us sooner or later: when you want to alter your display of the data, you will modify the values of these attributes, next you will have to recompile the business objects and then you will have to re-deploy those to both clients and servers. In my experience, customers always keep requesting UI enhancements, so this scenario will unfold some time for sure.

 

Yes I agree which is why I'm proposing to store in attribute only a refinement of the type of field.  I.E. a decimal would be refined as currency or quantity etc.  Currently we leave the actual display format up to the user by using their windows locale setting for any display purposes.

We do currently store a lot of display info in the database but more to do with Grid filtering, column order and sort order, form and tool bar layouts etc.

 

It's good to know that others are considering this as well.

Cheers!

hurcane replied on Thursday, May 18, 2006

We define the grid formatting in the database (for a WinForms app). Each grid has a record in the database that is keyed by an arbitrary code and the language. The records define the caption, the data type, and the alignment for each column.

A ColumnFormats business object exposes this. A custom grid control accepts ColumnFormats as a property and uses it to configure its display.

If your read-only collections use a stored procedure to retrieve the data, you can make changes based on user requests with database changes only. They want a new column? Add it to the stored procedure and add it to the tables that define the column formatting. Now the grid shows the extra column.

Some caution: Using an SP for each inquiry can lead to putting business logic in the database. Be careful when you are forced to write code that includes case statements, calculations, or complex where clauses. You should either change your data so the stored procedures don't need to think (i.e. the business objects do the thinking when writing the data) or use business objects.

JCardina replied on Thursday, May 18, 2006

hurcane:
We define the grid formatting in the database (for a WinForms app). Each grid has a record in the database that is keyed by an arbitrary code and the language. The records define the caption, the data type, and the alignment for each column.

I understand what you are saying, it's not exactly the same thing.  We do currently store the user's column order and hidden or shown columns in a business object, as well as the filter settings which they can choose from separately.

This is a bit of a different issue in that it involves the actualy formatting of the columns themselves.  For example one collection has a currency and a quantity field which are both decimal.  Previously we had code in the form that would set the grid column format to "c" for currency or set it for a quantity.

Or we would have special code to not show certain columns ever.  I.E. the user can right click on the grid header and bring up a list of fields to show or not show, but some fields / columns should never be shown because they are internal ID values or something.

What I'm thinking is that these are static unchanging properties of the fields which the user has no reason to change and so they best belong as close as possible to the source which leads to an attribute on the public property in the read only collection.

You mentioned stored procedures, that's a personal pet peeve of mine, I don't think they should be used in all but the most rarest of cases.  We started the current app we have published using stored procedures early on and quickly abandoned the idea as all but unworkable in the long term over the life of an application.

They just don't make sense most of the time but particularly when you have a data access layer and are supporting more than one type of db platform.  Performance is really a red herring these days, the power and freedom that dynamic sql (done securely of course) over stored procedures gives you more than outweighs the almost unmeasureable difference in performance. 

Also we found ourselves having more than double the maintenance to do because if you wanted to change a busines object you had 8 or 9 different places to make the changes whereas with dynamic sql you have two places the business object and the UI display form, and now with these attributes we can squish that down to one place to make the changes, only the business object.

Security is an issue we didn't want people messing with the stored procedures, it seems unlikely but it's definitely going to happen.  With the prior non CSLA version of the same app that we've been selling since 1999 we had numerous support incidents which turned out to be end users messing with the database for mysterious reasons.

Seriously I know stored procedures are pushed heavily in some camps, but after doing a lot of real world work with CSLA I've found they are just a means to their own end, you end up doing a lot of work just for the sake of the stored procedures for performance gains that are pretty much non-existant and can easily be outweighed by having more time to spend on developing the best schema, indexes and handling the data better in the UI.  Being able to go to one place to make a change to a business object is incredibly time saving and in my mind more correct design.

Phew! Sorry for the rant!

hurcane replied on Thursday, May 18, 2006

The columns object I suggested defines the formatting of the column (currency, quantity, boolean, etc), the text of the caption, and the alignment of the data. This is not the same as an object that defines the user customizations (i.e. column order, hidden columns). The columns object I described is not going to change at the user's whim. It only changes when the read-only business object changes.

Instead of code on the form to format the grid, subclass the grid and have it format itself. You still need a line of code on the form, but that line of code is just applying the object to the grid.

I also avoid stored procedures. I have to work with a VB6 legacy app, and it does inquiries with this concept of having database-driven column formatting. It uses stored procedures, but then 80% percent of the app's business logic is in the database, so we live with it.

RockfordLhotka replied on Thursday, May 18, 2006

To make this work in a broad sense, I suggest that you (at least mentally) make sure that your attributes are meaningful in Windows, Web (html/css) and WPF settings. As long as your attributes are broad suggestions and not technology-specific directives, then it seems like this is a perfectly good idea.

Of course this was the original idea behind html too - a set of suggestions on how to display content that a reader (browser) could use or ignore or interpret as the browser saw fit. Obviously that didn't work out too well in the end, because publishers (web site authors) wanted way too much control over the displayed results, and so html slowly morphed into a (pseudo-)prescriptive tag language much more akin to the control tags used by 1985-era word processing tools.

You run that same risk here. As long as you can keep these as suggestions you are all set. But when they become prescriptive you are in trouble, because you can't predict (or control) the future UI technologies that might be used (WPF, mobile devices, voice, etc.) and so any sort of prescriptive tagging scheme will become increasingly irrelevant and costly over time.

MelGrubb replied on Friday, May 19, 2006

Myself, I'd probably go even more extreme... as soon as I figure out how.  Instead of making these attributes mere "suggestions", I'd want to incorporate them into the business rules themselves.  If I tag a property as being a string with a maximum length of 30, then I don't think the business object should even ACCEPT anything longer.

Basically, if I put these attributes on my business object, then I'd want my object to enforce them.  This goes for things like ranges and regular expressions for validation as well.

RockfordLhotka replied on Friday, May 19, 2006

There's a different thread about exposing the business rule collection contained in the business object out to the UI developer. I think that is generally a good idea, but given the way rules are handled in CSLA, it is challenging to come up with a meaningful way to expose them to the UI. A rule, after all, is just a delegate pointer to a method, so coming up with a way to expose all that to the UI developer without incurring strong coupling is the challenge.
 
I viewed this thread as something different - the idea of exposing formatting suggestions.
 
While there could be some overlap, it is dubious that you'd have a validation rule dictating the color, font or layout of a bit of data - or even display format for that matter. So I think having some non-rule scheme for format suggestions isn't bad, but using attributes for rules would be a mistake, because that would duplicate the rules maintained by CSLA.
 
Rocky
 

Copyright (c) Marimer LLC