I've been working on a new project this past few days, as part of which we're using the Data Access Application Block from the Enterprise Library, which is OK (for a fairly low-level ADO.NET wrapper). One of the requirements we have is that we need to support dynamic connection strings, built at runtime, because we don't know the database server and database name we are connecting to until runtime. Now, I know this has security implications, but its required for reasons I don't plan on explaining here.
But here comes the rub: I looked everywhere, and was unable to find a way within the DAAB to support dynamic connection strings. There's just no way to create a SqlDatabase object having just a connection string (or at least the components thereof); the only way is to have it stored in the configuration file. This does us no good as a) we can't have a configuration file with that information because of what I said above and a few other reasons, and b) there's really no "known" set of database we allow connections to that can be set at deployment time.
I did end up finding a way, but I consider this a really ugly hack. The solution was to mimick the information in the configuration file by manually creating and filling an object of type DatabaseSettings, and then bypassing the normal initialization provided by the provider factory:
public DataBase Connect(string theServer, string theDatabase)
{
ConnectionStringData csd = new ConnectionStringData();
csd.Name = "X";
csd.Parameters.Add(new ParameterData("Server", theServer));
csd.Parameters.Add(new ParameterData("Database", theDatabase));
csd.Parameters.Add(new ParameterData("Integrated Security", "true"));
DatabaseTypeData sqldb =
new DatabaseTypeData("Sql Server", typeof(SqlDatabase).FullName);
InstanceData instance =
new InstanceData(csd.Name, sqldb.Name, csd.Name);
DatabaseSettings dbSettings = new DatabaseSettings();
dbSettings.ConnectionStrings.Add(csd);
dbSettings.DatabaseTypes.Add(sqldb);
dbSettings.Instances.Add(instance);
dbSettings.DefaultInstance = instance.Name;
DatabaseConfigurationView configView =
new DummyDatabaseConfigurationView(dbSettings);
SqlDatabase db = new SqlDatabase();
db.Initialize(_configView);
db.ConfigurationName = _dbSettings.DefaultInstance;
// now db is initialized
return db;
}
internal class DummyDatabaseConfigurationView : DatabaseConfigurationView
{
private DatabaseSettings _dbSettings;
///
/// Creates a new instance of the class
///
public DummyDatabaseConfigurationView(DatabaseSettings dbSettings)
: base(new ConfigurationContext())
{
_dbSettings = dbSettings;
}
public override DatabaseSettings GetDatabaseSettings()
{
return _dbSettings;
}
} // class DummyDatabaseConfigurationView
Is there really no other way? If the answer is no, please do take this into consideration for future versions!