Tuesday, August 18, 2009

When you need to write lots of code in a short amount of time

I needed to port a fairly sizable VB6 app to WinForms/C# in a short amount of time (~2months). One of the tricks to writing this much code quickly was to:
  1. Port 3 - 5 menu elements that were representative a most of the menu elements.
  2. By the time you get to the 3rd menu element some common patterns emerge.
  3. Put those common patterns into a code snippet and reuse the code snippet for the remaining menu elements.
  4. Repeat steps 1 - 3 for each "class" of menu element (where a class includes all menu elements that execute similarly).

Exception handling in event handlers was low hanging fruit. Sometimes an Exception occurs at a location where I have information that can make the error message more useful. e.g., An IO Exception that occurs in 1 part of a multistep process makes more sense if the multistep process is included in the error message.

So I made a code snippet with a try/catch (ApplicationException)/catch (Exception). If the Exception can be made more useful then it gets wrapped in ApplicationException-derived Exception, otherwise just let it bubble up.

This code snippet would be the first thing I'd include in any new menu event handler.

Another trick was taking advantage of the DynamicInvoke() method of delegates. Most of the menu event handlers opened a dialog window, retrieved input from the user then passed that input to a method call in another library. The library would create a new output file as a result. There were 40 - 60 of these kinds of dialog boxes.

Instead of separately doing this input setup/marshalling and output handling it was easier to have each of these dialogs package their input along with a delegate to the underlying library call to a single method. This method would execute the call (via DynamicInvoke()) and return the results to the caller.

Turns out that this "wrapper around DynamicInvoke()" ended up being a natural place for adding context to error message. This context makes it much easier to debug when you receive a screenshot of the exception message from a client in the field.

A final trick was to make use of Visual Inheritance. Since so many of the menu elements open a dialog window, get input from the user, execute 1 or more steps, etc... some of this functionality was combined into a base form from which all other dialogs derived. The base form took care of positioning the OK and Cancel buttons, a descriptive paragraph near the top of the form and incorporating progress in the status bar of the dialog window. Each of the 40 - 60 dialog windows then derived from the base form.

No comments :

Post a Comment