I inherited a solution with many projects, and one of them contains hard coded database connection parameters. These are referenced in a number of other projects, and many of those are dependencies of the entry assembly. The solution has multiple entry assemblies or deployment units, intended as microservices.
My first goal is to remove the hard coded db username/password, but I can't restructure the solution dramatically, or create multiple solutions within the git repo. I'm thinking of creating a new project within the solution that returns app settings of the entry assembly, at which point the db params can be placed in the app config files for each of the web projects, and removed from hard coded struct where they are currently defined.
using System.Collections.Specialized;
using System.Reflection;
namespace DMConfiguration
{
public static class ConfigurationManager
{
private static NameValueCollection _settings;
private static readonly object LOCK = new object();
/// <summary>
/// Gets the AppSettings from the entry assembly
/// </summary>
public static NameValueCollection AppSettings
{
get {
if (_settings == null)
{
lock (LOCK)
{
if (_settings == null)
{
var appSettings = new NameValueCollection();
var config = System.Configuration.ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
foreach (var key in config.AppSettings.Settings.AllKeys)
{
var kv = config.AppSettings.Settings[key];
appSettings.Add(key, kv.Value);
}
_settings = appSettings;
}
}
}
return _settings;
}
}
}
}
I ran this in a small throwaway solution to see if it produced the desired results, and it does. For example, from my main console project, I call into ClassLibrary2:
using DMConfiguration;
using System;
namespace ClassLibrary2
{
public class ClassTwo
{
public void Talk()
{
// notice familiar interface for accessing app settings
var myValue = ConfigurationManager.AppSettings["MyKey"];
Console.WriteLine("ClassLibrary2 says " + myValue);
}
}
}
However, despite some searching, I have not found any information regarding the wisdom of this approach. Before I commit to it, I'd appreciate any feedback about potential problems that might come up.
1 Answer 1
Maybe i have missunderstood something, but it's not clear to me why not simply access the right file AppSetting as you already do, thought ConfigurationManager class and providing the right path.
If for simplicity you would "cache" the result, i would sugget a stati class with a static constructor that will store result in a property (should be thread safe and CofigurationManager definly is).
I mean something as follow :
public static class CMWrapper
{
public static AppSettingsSection AppSettings { get; private set; }
static CMWrapper ()
{
if ( CMWrapper.AppSettings == null )
CMWrapper.AppSettings = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location).AppSettings;
}
}
ConfigurationManager
to avoid confusion. you can use a prefix to distinguish them. \$\endgroup\$