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.
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: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: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!
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.
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.
Copyright (c) Marimer LLC