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?
3 Answers 3
I don't do much asp.net, 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.
-
\$\begingroup\$ it does work the same for a
web.config
file, it's the same thing as aapp.config
file except it's for a web application. \$\endgroup\$Malachi– Malachi2014年05月21日 17:54:49 +00:00Commented May 21, 2014 at 17:54 -
3\$\begingroup\$ This might be of interest: haacked.com/archive/2007/03/12/… \$\endgroup\$Mathieu Guindon– Mathieu Guindon2014年05月21日 17:56:02 +00:00Commented May 21, 2014 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– Malachi2014年05月21日 18:00:19 +00:00Commented May 21, 2014 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– Rakuen422014年05月23日 13:00:42 +00:00Commented May 23, 2014 at 13:00
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
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.
-
\$\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– Raystafarian2018年04月07日 14:10:42 +00:00Commented Apr 7, 2018 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– cedd2018年04月08日 18:45:13 +00:00Commented Apr 8, 2018 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– Raystafarian2018年04月08日 22:57:43 +00:00Commented Apr 8, 2018 at 22:57
-
\$\begingroup\$ OK, I've made an edit ... \$\endgroup\$cedd– cedd2018年04月09日 18:10:56 +00:00Commented Apr 9, 2018 at 18:10