We are about to implement an application using winforms. I would like to have a 3 layer architecture (GUI, Business Logic and Data Access Layer.
We have one database per customer, so we must be able to access different databases (possible on different servers as well) using the application. E.g. Customer A is on server A and Customer B is on server B.
EDIT: Deployment scenario: This application may be installed on ServerA, but the databases might be on ServerA, ServerB, ServerC, ServerX (I think you get the picture).
Reading the db connection from a database is then somewhat complicated since I don't know which db the user wants to connect to. And to top it off the user ids are only unique in the same db, so a user with the username e.g "admin" can exists in multiple databases:)
We would like to be able to log on the application providing a user name, password and connection string information. Now, how do you send the connection string information to the DAL, so that the GUI nor the Business Layer doesn't have to have a knowledge of the database connection string? I would not like to store the connection string in the GUI project and pass that as a parameter to the Business Layer that in turns passes the connection string to the DAL every time I need some data in the database.
EDIT: The connection string information only need to be available while the user is logged in. As soon as he logs out this information should be deleted)
I have implemented a class in an new project that inherits from ApplicationSettingsBase (Both the UI project and the DAL project have a reference to the new project). So I'm now able to persist the connection information (to a user.config file by default). So I can instantiate that class from the User interface and store the connection information by calling base.Save on my class and then in the DAL I can instantiate the same class and read the connection information there. Not sure if I like that solution because the user.config file is tied to the windows user (by storing the file in the C:\Users...\AppData\ hierarchy and I'm not sure about the performance by doing it this way. Overkill maybe?
EDIT: I have not been able to find a satisfactory solution yet, so I appreciate more answers from the community:)
EDIT:
I found a way to solve this. I have only testet the solution in a small test project, but here goes:
The user logs in and the UI methods responsible for retrieving the login information runs this method:
public void SetTempSetting()
{
// Get the configuration file.
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Add the connection string.
ConnectionStringsSection csSection = config.ConnectionStrings;
csSection.ConnectionStrings.Add(new ConnectionStringSettings("ConnectionStringName", GetConnectionString()));
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
}
The SetTempingSetting() method will write the connectionstring to the ProjectName.dll.config
And in the DAL project I can get the connectionstring from the ConfiguraionManager like this:
var connectionstring = ConfigurationManager.ConnectionStrings["ConnectionStringName"].ConnectionString;
And when the user logs out of the application the logout method can execute this method to delete the connectionstring from the Project.dll.config
public void RemoveTempSetting()
{
// Get the configuration file.
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// Add the connection string.
ConnectionStringsSection csSection = config.ConnectionStrings;
csSection.ConnectionStrings.Remove("ConnectionStringName");
// Save the configuration file.
config.Save(ConfigurationSaveMode.Modified);
}
Any thoughts on this solution? Pros? Cons? Overengineered? Bad design?