7
\$\begingroup\$

Let's say I have a configuration file with a property in it:

<add key="LoadedCode" value="L" />

I know I can reference this using the ConfigurationManager:

System.Configuration.ConfigurationManager.AppSettings["LoadedCode"];

This has some drawbacks. It can get bulky when it gets used in multiple locations. I lose support for refactoring and "Find All References" because I'm using an item in the AppSettings collection. I don't have strong-typing in cases where the config setting isn't a string. So I wrap it into a static property in a static class:

public static string LoadedCode
{
    get { return System.Configuration.ConfigurationManager.AppSettings["LoadedCode"]; }
}

Great so far. Now I want to use this on multiple pages and this leads me to my conundrum. Should I reference this static property everywhere, or should each page have its own local wrapper?

On the one hand, a local wrapper pushes all uses on the page through a single point which can be modified without impacting other pages if needed. On the other hand, it adds a layer of indirection to the dependency chain and it looks a bit like overkill.

Is there a best practice for this type of behavior, or am I simply over-thinking things?

\$\endgroup\$
11
\$\begingroup\$

I don't do much , but if this StackOverflow answer applies then you could just do this:

using Settings = MyProject.Namespace.Properties.Settings;

var loadedCode = Settings.Default.LoadedCode;

Like this other StackOverflow answer is saying:

We prefer to use Properties.Settings (aka. settings.settings) because it's strongly typed.

Now I know for a fact that this works with an app.config, but it might not work with a web.config file... but I think it's worth trying.


Alternatively, this Haacked article describes how to use the configuration API to define your own ConfigurationSection classes, which would be the ultimate way to address this issue. Might be overkill if the above works though.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ it does work the same for a web.config file, it's the same thing as a app.config file except it's for a web application. \$\endgroup\$ – Malachi May 21 '14 at 17:54
  • 3
    \$\begingroup\$ This might be of interest: haacked.com/archive/2007/03/12/… \$\endgroup\$ – Mathieu Guindon May 21 '14 at 17:56
  • \$\begingroup\$ I think you are right, I don't think I fully understood the question. that link in your comment is more along the lines of this question I think \$\endgroup\$ – Malachi May 21 '14 at 18:00
  • 1
    \$\begingroup\$ That haacked article answered my question in a way I didn't expect. I never thought about using the configuration API. That gives me the benefits of a property approach while also letting me shape the config in a more natural way. I'll mark this as the answer and I encourage you to move that up into your post's body. \$\endgroup\$ – Rakuen42 May 23 '14 at 13:00
1
\$\begingroup\$

You shouldn't have to use the fully qualified name, you should be able to do something like this

using System.Configuration;

public static string LoadedCode
{
    get { return ConfigurationManager.AppSettings["LoadedCode"]; }
}

I think you can even go farther depending on how you set up your References and Web.Config File

What I do is create my variable and set it to the value of the Configuration that I need, so this is where you would "convert" it to the right type. Doing it this way you also only retrieve the data if you need it.

String loadedCode = Convert.ToString(ConfigurationManager.AppSettings["LoadedCode"]);

And then when you need to use that value you just call loadedCode

I don't see a reason to create a method just to grab this unless it is going to be used by the entire class and you don't want it available outside the class, then you would have something like this

private static string _loadedCode = ConfigurationManager.AppSettings["LoadedCode"];

And then you would call it accordingly as _loadedCode

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

I have faced similar problems and have had similar thoughts. I have written a nuget package to do more or less what you describe.

Firstly I define an interface with all the configuration that my class needs. In this case

public interface ILoadingConfiguration {
    string LoadedCode { get; }
    ... etc
}

Then I alter my class to take this configuration via constructor injection

public class ClassThatNeedsLoadedCode {
    public ClassThatNeedsLoadedCode (ILoadingConfiguration configuration) {
        ...
    }
}

Then I define a class that handles all the configuration for my application.

public class MyApplicationConfiguration: ILoadingConfiguration, ISomeOtherConfiguration, etc {
    public string LoadedCode { get; }
    ... other configuration
}

Then I pass this class into all classes that need it using some kind of Depenendency Injection (normally Castle Windsor or AutoFac for me).

If it is too difficult to do this (presumably for legacy type reasons), I define a static version of MyApplicationConfiguration and access this directly.

More details on this blog post.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Instead of linking to the information, please put it in the answer. It's better to have it here in case the links go bad. \$\endgroup\$ – Raystafarian Apr 7 '18 at 14:10
  • \$\begingroup\$ Hi there. I think this is ok. My answer to the original question is that I would recommend trying for dependency injection when you can, but fall back to a public static if its too difficult / time consuming to do so. The links have some details of how you might do this, but that is kind of a side issue to the main question, and it would make the answer a lot longer and harder to read if I were to include all the detail \$\endgroup\$ – cedd Apr 8 '18 at 18:45
  • \$\begingroup\$ Perhaps one example of the original code done in your way would be a good addition? It's your answer and I'm not trying to tell you how it should be (: \$\endgroup\$ – Raystafarian Apr 8 '18 at 22:57
  • \$\begingroup\$ OK, I've made an edit ... \$\endgroup\$ – cedd Apr 9 '18 at 18:10

Not the answer you're looking for? Browse other questions tagged or ask your own question.