Michael Stum
Michael Stum

Reputation: 180914

Initialization code in a WinForms App - Program.cs or MainForm?

I have a Windows Forms application that currently loads a database on startup. The flow is like this:

Program.cs => Application.Run(new MainForm()); => MainForm Constructor => Open Database

So basically MainForm holds all the bits and pieces that make the application run, while Program.cs is just a stub. Currently, the name of the database that is loaded is hardcoded, and I want to add functionality to specify the name of the database to load through the command line. At the same time, I want to add the ability to do some Unit Testing or even Dependency Injection later on, so I wonder which approach is recommended?

Method one seems to be cleaner as it would allow i.e. a Test runner to create MainForm with a test database, but as I'm usually not a WinForms developer I do not know if there could be side effects of not having a default constructor on the Main Form or if there is a better approach?

Upvotes: 2

Views: 9804

Answers (3)

Chernikov
Chernikov

Reputation: 857

You can create a Singleton object (or lazy initialization) for manage DB, and initialize it in any part of code:

public class DBProvider() 
{
    private static string DefaultConnectionString = "some connection string";
    private static DBProvider instance 
    public static DBProvider GetInstance() 
    {
        get 
        {
            if (instance == null) 
            {
                instance = new DBProvider(DefaultConnectionString);
            }
            return instance;
        }
    }

    public DBProvider(string Connection string) 
    {
        ...
    }


    public static void Initialize (string ConnectionString) 
    {
        instance = new DBProvider(ConnectionString);
    }
}

And you can initialize it in Program.cs or in MainForm ctor and use DBProvider.GetInstance();

Upvotes: 0

flq
flq

Reputation: 22839

Currently, I configure a Dependency Injection Container within Program.cs and then say

Application.Run(container.GetInstance<Form>());

The application we are currently developing has about 80 different application parts. Our MainForm currently clocks in at 95 lines of code and has dependencies to an IApplicationModule (an interface whose only property is to return a "TopControl"), a MenuStripModule, a StatusBarModule and a Session object.

Upvotes: 2

Kevin Jones
Kevin Jones

Reputation: 2367

I think this comes down to a separation of concerns. The Program class should be concerned with application level details and the MainForm with form details. This then says to me that that Program should parse the command line and pass the names to the form.

You could still leave the default constructor on the form and either mark it private or throw an error if you execute it. Or you could still have Program.cs use the default constructor to create the form and simply inject the database name with paramters (so it's either constructor injection or parameter injection), something like

form = new MainForm();
form.DbName = "foo";
Application.Run(form);

Upvotes: 5

Related Questions