You can Download Source Code from here.
Introduction
In this article we will discuss about a design through which we can achieve extreme customization. In one of my article I have explained about Model View Controller design pattern which can be used achieve customization. The entire model of customization in MVC depends upon inheritance at any level. This needs periodic and effective code reviews. The success of customizability in MVC depends upon the way the developer does coding. If the developer doesn’t provide appropriate overridable hooks then the entire code looses the fame of customization. Even though we have very good processes in our company to do code reviews we cannot expect the reviewer to review the code by keeping customizability as one of the point. This ends upon in reviewing each and every function and its importance against customizability. Code reviews are necessary but it cannot give guarantee that all the reviewed code is customizable. This is a know secret. In this article I am trying to put forward a design that will make customizability as one out of box feature. Every developer’s code which has been coded in this design is eligible for customization. This design applies to winforms application development.
What makes code hardwired?
When we start coding in vs.net (winforms), all the code we write like events, custom functions, properties etc are getting burnt in the same file itself. This it-self make the code hardwired. Even though we might have created some class libraries to do code for some common functions all the events related to the form are getting hardwired. The code which we write in event subroutines cannot be changed easily. According to MVC View should not have any code in it. The same issue has been discussed with my team in my current project many times. But we are not able come to a design which will help us to achieve customizability as out of box feature. Then we got a design in which the entire form is driven through a configuration. This will help us to change things in runtime. For example if we have a form which has 3 controls, the form will not know about the control events in design time. Subroutines are created in a separate controller class and the same will get associated to the control event based on the information which is stored in an xml file. Initially we stated with XML file and we changed the data store to database for scalability. This is not a new idea flashed in my teams mind. This is an old approach which has been used my many ERP packages like SAP. In SAP entire UI is driven through DB. In SAP they even paint the UI based on the configuration data which is stored in the DB. This is one of the feature which highlights SAP as one of the leading ERP package.
Lets get into Internals
Before getting into the design let us answer some of the basic questions which rose in my minds.
1. How to make a form which is free from any code to achieve re-usability of form across functional point?
This can be achieved using MVC pattern. The main disadvantage in this approach is “Customizablity” depends upon the person who code. No Form should know about the functionality, Form should be just a blank UI representation and the functionality will get attached to the form in runtime based upon configuration.
2. In this design, all the details about the form will get stored in DB. To do this we will provide a tool which helps the developers to do the configuration.
3. Based upon the configuration, form reacts in runtime.
Form Configuration Tool
This is a simple tool which helps the developers to configure the form details to database tables. This tool is very basic; this can be extended to our requirement. Before getting in to form configuration, let me explain what form configuration does by answering some set of questions.
1. How form configuration tool identifies forms?
The forms which needs to get configured using this tool, should get tagged with FormIDAttribute which takes a guid parameter. The guid supplied by the developer’s acts as the basic identification for a form. The same guid is stored in database and used in further configuration for the form.
2. What information the tool captures from the user?
User selects a assembly All the types which have the FormIDAttribute attribute tagged will get displayed in another combo box. Two tab pages (Controllers & Events) shows the configured details (if any). Both Controllers and Events tab has new and delete buttons to add and delete controllers and events.
3. What are controllers?
Controllers are nothing Assembly & Class combination which implements a particular interface.
4. What data does the Events Tab collects
Form -> Controls–Events Event handlers can be in any assembly –class combination which implements a particular interface. Since event handlers are configured in data base, it is easy to change the existing functionality and also to add new functionality.

Creating a sample Customizable Form
1. Create a new database and run the downloaded DB script file. This will create appropriate tables and stored procedures.
2. Compile CustomizableForms.sln which is available as sample download.
3. Add a reference to CustomizableForms.dll to the project.
4. Create a new Windows Application Project (MyTestForm) and add a new form named “Form1”
5. Go to the code view of Form1 and change the inheritance of Form1 from “System.Windows.Forms.Form” to “CustomizableForms.FormBase”
6. Go to the constructor of the Form and add the following lines of code after InitializeComponent method. Mybase.Onit()
7. Place a button in the Form (“Button1”)
8. Add <CustomizableForms.FormID("")>_ attribute to the form.
9. Create another class named” MyController and inherit the class from ControllerBase class and add controller attribute to the class.
<CustomizableForms.FormID("")> _ Class Form1 Inherits CustomizableForms.FormBase Public Sub New() MyBase.New() InititializeComponent() MyBase.OnInit() ‘ Call this after initializecomponent End Sub End Class
<CustomizableForms.ControllerID("{1EBB9B16-026C-4131-925D-EF9ABB530FD4}")> _ Public Class mycontroller Inherits ControllerBase // All the Events handlers come here. Public Sub btnAdd_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Msgbox(“Hello World”) End Sub End Class
10. Run CustomizanleForm.sln and click on the FormConfigurator Menu from the tools section.
11. Click on the browse button and select the assembly which we have created now (TestForm.dll).
12. It will list Form1 in the combo.
13. Click on the New button in the ControllerTab and select the MyTestForm.dll
14. Combo box will list all the available controllers in the assembly
15. Select MyController and click Add button.
16. Click the event tab and click New button
17. Select the “Button1” from the controls combo.
18. Events combo will show all the events of the button.
19. Select “Click” event.
20. Controllers combo will list all the configured controllers
21. Select MyController from the combo box.
22. Subroutines Combo will show “btnAdd_Click” subroutine.
23. Select the subroutine and click add.
After configuring the form, run the MyTestForm.sln and load Form1. Clicking on the button will prompt the message box with “Hello world” as string. Like this we can configure events of all the controls in a form in different controllers. This helps us to achieve customization in runtime.
Enhancements
1. Context Object can be passed to all the controllers which carry some information which can be shared between controllers. For Example Controller can access the instance of the other controllers.
2. Currently the base class expects the connection string from the executing assembly’s configuration file. This can also be fetched from registry. Each and every application’s configuration file should have the following entry.
<add key="ConnectionString" value="server=localhost;database= FormCustomization;uid=sa;pwd=sa;"/>
Disadvantages of using this approach
1. Increases development time Yes this approach increases development time, but we get customization as output.
2. Performance is little slow when we compare normal application development. Now-a –days all client desktops are having good configuration. If we have good configurations machines we cannot feel the performance hit. Caching the data will solve this issue.
3. Lot of configuration needs to be scripted as insert scripts and the same should get included in final deliverable. No gain without pain!!!!!!!!!
Download Source Code
|
| Author: dominique Gratpain 19 Jul 2005 | Member Level: Bronze Points : 0 |
very good article but i don't see where are the download code and sql
cheers
Dominique
|
| Author: critic 20 Jul 2005 | Member Level: Bronze Points : 0 |
Source code has been attached with the article. You can download it now.
|