I got a question today in an article I published about the fluent configuration API in Enterprise Library 5. The question was how to add a database connection string to an existing configuration during runtime. The person who wrote the question also published a specific solution which I refactored to a general purpose solution that I’ll show in this post.
The Problem
When you use the fluent configuration API, the ConfigurationSourceBuilder
class has just one method to update the configuration which is UpdateConfigurationWithReplace
. This method updates the configuration source and replaces any existing sections with those built up with the builder. If during runtime, we want to update the configuration without replacing the current configuration, we have a problem.
The Solution
Use the System.Configuration
API to get the current configuration and add it to the new configuration you build. Here is an implementation of how to copy all the current connection strings by using the IDataConfiguration
which is part of the fluent configuration API:
private static void CopyCurrentDataConfiguration(IDataConfiguration dataConfig)
{
var configSource = ConfigurationSourceFactory.Create();
var dataConfigurationSection = (DatabaseSettings)configSource.GetSection(
DatabaseSettings.SectionName);
var defaultDatabaseName = dataConfigurationSection.DefaultDatabase;
CopyConnectionStrings(dataConfig, defaultDatabaseName);
}
private static void CopyConnectionStrings(IDataConfiguration dataConfig,
string defaultDatabaseName)
{
foreach (ConnectionStringSettings settings in ConfigurationManager.ConnectionStrings)
{
var configuredDatabase = dataConfig
.ForDatabaseNamed(settings.Name)
.ThatIs
.AnotherDatabaseType(settings.ProviderName);
if (settings.Name.Equals(defaultDatabaseName))
{
configuredDatabase.AsDefault();
}
}
}
In the first method, I retrieve the Enterprise Library database settings and save the default database name. Then I use the second method to configure all the current connection strings. Since the database provider isn’t known, I use the AnotherDatabaseType
method to add the providers. Here is an example of how to use these methods to add another connection string to your configuration:
public void AddNewConnectionString(string databaseName, string connString)
{
var builder = new ConfigurationSourceBuilder();
var dataConfig = builder.ConfigureData();
CopyCurrentDataConfiguration(dataConfig);
dataConfig
.ForDatabaseNamed(databaseName)
.ThatIs
.ASqlDatabase()
.WithConnectionString(connString);
var newConfigSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(newConfigSource);
EnterpriseLibraryContainer.Current =
EnterpriseLibraryContainer.CreateDefaultContainer(newConfigSource);
}
Summary
The lack of current support to only updates without replacing the configurations in the fluent configuration API can cause you trouble when you need that behavior. In the post, I showed a workaround to configure the EnterpriseLibraryContainer
without replacing the current configurations for connection strings. This method can be applied to other configurations as well but you’ll have to write code to achieve that.