1
\$\begingroup\$

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.

asked Aug 10, 2022 at 15:35
\$\endgroup\$
6
  • \$\begingroup\$ does the original project works with multiple databases or just one database ? is it possible to create a library class within the solution to be used as Data Access Layer? \$\endgroup\$ Commented Aug 10, 2022 at 17:36
  • \$\begingroup\$ @iSR5, it's a single database, and there is an intended data access layer, but there are multiple projects reaching in for the hard coded constants. I just reviewed the call hierarchy, and it looks like 5 of 10 web projects will ultimately depend on them. I'm thinking I can add those values to the app.config of each of those projects, and use something like what I posted. \$\endgroup\$ Commented Aug 10, 2022 at 17:44
  • \$\begingroup\$ I should add that the entire codebase is atrocious, as you can probably guess since they hard coded something like that. \$\endgroup\$ Commented Aug 10, 2022 at 17:52
  • 2
    \$\begingroup\$ then I guess your approach is feasible, however, you should avoid class names that are already used in .NET, such as ConfigurationManager to avoid confusion. you can use a prefix to distinguish them. \$\endgroup\$ Commented Aug 10, 2022 at 17:58
  • \$\begingroup\$ Thank you @iSR5 for taking a look. I appreciate the advice. \$\endgroup\$ Commented Aug 10, 2022 at 18:05

1 Answer 1

1
\$\begingroup\$

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;
 }
}
answered Aug 26, 2022 at 22:39
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.