When Eric hired Carl to teach me .Net and help develop a framework, neither Carl nor myself had any idea what we were in for. Carl aptly suggested using business objects, and he pointed out that the binding object was a great place to start. We continued on our merry ways, until we realized that designing screens at design time might be a bad practice in our environment. At first we discussed dynamic screen design, but then decided against it as the layout would be difficult to get right each time.
As it turns out, we ended up using this exact paradigm. We also included our database select strings, and information about how data should be presented and validated. This allowed us to change any facet of an application at run time. No recompilation worries there.
Things aren't so simple now. Changes to the database get requested between code releases, and these changes can get incorporated into one configuration, but not another. This has caused me to question the wisdom of the approach that Carl and I took. This week at DevTeach has offered me an opportunity to once again question our approach. How better might I do things? There are some things I would do differently. I might migrate to pluggable, dynamically loaded objects to represent rows in a table. Validation would move into these objects and out of the config file. These objects should also be nested to reflect a schema.
At the end of the day, though, it still makes no sense to design each screen individually. Our design metaphor is still valid. The only problem is how to integrate changes to the live configuration (I can change a lot of screens without touching any code!) into the next development release. I designed a tool for combining configuration versions. It still needs some work, but it does its job. Carl had the knowledge, and I lacked the knowledge...which made it possible for me to ask why we would build each screen, bind each control, and fill each label.
The next iteration should have strong typing. Why? Because strong typing makes more robust code. We need intermediate objects to represent individual items, before they are aggregated into tables. That's where validation belongs. That's where schema should be represented. The bindingsource shouldn't update and validate, it should ask its constituent objects to do that.
The best part of all? The atomic elements become fields. At the record level, objects aggregate fields. Let's let the fields tell us how they should be represented. When I'm done tearing everything out of the configuration and placing it in intermediate objects, who knows...maybe the configuration will become manageable again!