Reputation: 180914
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?
Application.Run(new MainForm());
accordinglyMethod 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
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
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
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