
When using C#, I am kinda a strongly typed bigot and like to use the compiler as much as I can. Since practically every application I have ever worked on has had some sort of setting access from a config file, I felt that there had to be a better way.
So, given this config file:
<?xml version="1.0" encoding="utf-8" ?>
<add key="StringSetting" value="filepath"/>
<add key="BoolSetting" value="true"/>
<add key="StringListDelimitedSetting" value="one;two;three"/>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="StringSetting" value="filepath"/>
<add key="BoolSetting" value="true"/>
<add key="StringListDelimitedSetting" value="one;two;three"/>
</appSettings>
</configuration>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="StringSetting" value="filepath"/>
<add key="BoolSetting" value="true"/>
<add key="StringListDelimitedSetting" value="one;two;three"/>
</appSettings>
</configuration>
I don’t want to litter my code with this everywhere:
string value = System.Configuration.ConfigurationManager.AppSettings["StringSetting"];
if (value == "SOMETHING")
string boolValue = System.Configuration.ConfigurationManager.AppSettings["BoolSetting"];
//PRODUCES STRONG TYPE BUT EVEN MORE CODE
string someOtherBoolValue = System.Configuration.ConfigurationManager.AppSettings["SomeOtherBoolSetting"];
if (Boolean.TryParse(someOtherBoolValue, out strongBoolValue))
//BAD
string value = System.Configuration.ConfigurationManager.AppSettings["StringSetting"];
if (value == "SOMETHING")
{
//do something
}
//WORSE?
string boolValue = System.Configuration.ConfigurationManager.AppSettings["BoolSetting"];
if (boolValue == "YES")
{
//do something
}
//PRODUCES STRONG TYPE BUT EVEN MORE CODE
string someOtherBoolValue = System.Configuration.ConfigurationManager.AppSettings["SomeOtherBoolSetting"];
bool strongBoolValue;
if (Boolean.TryParse(someOtherBoolValue, out strongBoolValue))
{
if (strongBoolValue)
{
//do something
}
}
//BAD
string value = System.Configuration.ConfigurationManager.AppSettings["StringSetting"];
if (value == "SOMETHING")
{
//do something
}
//WORSE?
string boolValue = System.Configuration.ConfigurationManager.AppSettings["BoolSetting"];
if (boolValue == "YES")
{
//do something
}
//PRODUCES STRONG TYPE BUT EVEN MORE CODE
string someOtherBoolValue = System.Configuration.ConfigurationManager.AppSettings["SomeOtherBoolSetting"];
bool strongBoolValue;
if (Boolean.TryParse(someOtherBoolValue, out strongBoolValue))
{
if (strongBoolValue)
{
//do something
}
}
So, this is what I do to keep my “stringly” typed settings in one place, strongly typed and make them easily accessible in my code:
public static class AppSettingsExtensions
public static string StringSetting(this NameValueCollection settings)
string setting = settings["StringSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
public static bool BoolSetting(this NameValueCollection settings)
string setting = settings["BoolSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
if (Boolean.TryParse(setting, out test))
public static IEnumerable<string> StringListDelimitedSetting(this NameValueCollection settings)
string setting = settings["StringListDelimitedSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
return setting.Split(Convert.ToChar(";"), Convert.ToChar(",")).ToList();
return Enumerable.Empty<string>();
public static class AppSettingsExtensions
{
public static string StringSetting(this NameValueCollection settings)
{
string setting = settings["StringSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
{
return setting;
}
return string.Empty;
}
public static bool BoolSetting(this NameValueCollection settings)
{
string setting = settings["BoolSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
{
bool test;
if (Boolean.TryParse(setting, out test))
{
return test;
}
}
return false;
}
public static IEnumerable<string> StringListDelimitedSetting(this NameValueCollection settings)
{
string setting = settings["StringListDelimitedSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
{
return setting.Split(Convert.ToChar(";"), Convert.ToChar(",")).ToList();
}
return Enumerable.Empty<string>();
}
}
public static class AppSettingsExtensions
{
public static string StringSetting(this NameValueCollection settings)
{
string setting = settings["StringSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
{
return setting;
}
return string.Empty;
}
public static bool BoolSetting(this NameValueCollection settings)
{
string setting = settings["BoolSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
{
bool test;
if (Boolean.TryParse(setting, out test))
{
return test;
}
}
return false;
}
public static IEnumerable<string> StringListDelimitedSetting(this NameValueCollection settings)
{
string setting = settings["StringListDelimitedSetting"];
if (setting != null && !string.IsNullOrWhiteSpace(setting))
{
return setting.Split(Convert.ToChar(";"), Convert.ToChar(",")).ToList();
}
return Enumerable.Empty<string>();
}
}
Accessing settings in code now is simple and gives you a strong type:
string stringSetting = ConfigurationManager.AppSettings.StringSetting();
if (stringSetting == "SOMETHING")
bool boolSetting = ConfigurationManager.AppSettings.BoolSetting();
IEnumerable<string> listSettings = ConfigurationManager.AppSettings.StringListDelimitedSetting();
foreach (string setting in listSettings)
//GOOD
string stringSetting = ConfigurationManager.AppSettings.StringSetting();
if (stringSetting == "SOMETHING")
{
//do something
}
//OR
bool boolSetting = ConfigurationManager.AppSettings.BoolSetting();
if (boolSetting)
{
//do something
}
//OR
IEnumerable<string> listSettings = ConfigurationManager.AppSettings.StringListDelimitedSetting();
foreach (string setting in listSettings)
{
//do something
}
//GOOD
string stringSetting = ConfigurationManager.AppSettings.StringSetting();
if (stringSetting == "SOMETHING")
{
//do something
}
//OR
bool boolSetting = ConfigurationManager.AppSettings.BoolSetting();
if (boolSetting)
{
//do something
}
//OR
IEnumerable<string> listSettings = ConfigurationManager.AppSettings.StringListDelimitedSetting();
foreach (string setting in listSettings)
{
//do something
}
And yes, this works for connections strings as well, just change the type of the extension:
public static class ConnectionStringExtensions
public static string SomeConnectionString(this ConnectionStringSettingsCollection settings)
ConnectionStringSettings setting = settings["SomeConnectionString"];
string connectionString = setting.ConnectionString;
if (!string.IsNullOrWhiteSpace(connectionString))
public static class ConnectionStringExtensions
{
public static string SomeConnectionString(this ConnectionStringSettingsCollection settings)
{
ConnectionStringSettings setting = settings["SomeConnectionString"];
if (setting != null)
{
string connectionString = setting.ConnectionString;
if (!string.IsNullOrWhiteSpace(connectionString))
{
return connectionString;
}
}
return string.Empty;
}
}
public static class ConnectionStringExtensions
{
public static string SomeConnectionString(this ConnectionStringSettingsCollection settings)
{
ConnectionStringSettings setting = settings["SomeConnectionString"];
if (setting != null)
{
string connectionString = setting.ConnectionString;
if (!string.IsNullOrWhiteSpace(connectionString))
{
return connectionString;
}
}
return string.Empty;
}
}
Accessed like:
string connectionString = ConfigurationManager.ConnectionStrings.SomeConnectionString();
string connectionString = ConfigurationManager.ConnectionStrings.SomeConnectionString();
string connectionString = ConfigurationManager.ConnectionStrings.SomeConnectionString();
And there you have it, that is a tool I like to keep in my toolbox when working with configuration files.
Be First to Comment