Saturday, February 21, 2009

Application.Run and Controller-View Separation

When starting a new WinForms application, Visual Studio provides you with some defaults to help you get you started. Two of these are the Program.cs file and a child of the Form class as the project's first window. In the Main method of Program.cs, you will see the following code:
Application.Run(new Form1());
It is here that Microsoft starts you off on the wrong foot. The natural place to start, given this setup, is to add logic to the Form (which is the View). By making the View the starting point of the application, proper architecture is discouraged from the beginning.

All is not lost however. There is an overload for Application.Run that takes an ApplicationContext. Simply create a Controller, that extends ApplicationContext, and have it take a reference to the View. This design encourages logic to be placed in the Controller which can then drive the View. Easier unit testing is one of many reasons such a design is superior.
// Controller.cs
public class Controller : ApplicationContext
{
    private readonly Form1 _view;

    public Controller(Form1 view)
    {
        _view = view;
    }   
}

// Program.cs

// in Main
Application.Run(new Controller(new Form1());

This simple change in default setup has a dramatic architectural effect on the application going forward. While many experienced developers will invert the default relationship, as shown in the snippet above, it leads novice .NET developers down the wrong path unnecessarily. Why make a superior architecture available but not make it the default?

0 comments:

Post a Comment