What are the best practices for using the Properties.Settings.Default config settings in C#? I see it commonly, but I often don't know when to utilize it vs. when I should just hard code values. Thanks!
Basically, I try to avoid hardcoding values in code, mainly because if there's ever a need to change their value it requires a re-compile of the app.
It's usually beneficial to have some sort of common object that exposes all your settings via public properties so that you are referencing the settings the same way throughout the app.
Example:
public static SomeReferenceClass
{
public static string TimeOfDay { get{ return Properties.Settings.Default.TimeOfDay; }}
}
Then Later on to call it
SomeReferenceClass.TimeOfDay;
My rule of thumb has always been that if the values of the properties need to change without modifying the code then make them an external/configurable property. If you will never need to change their value, then they're a constant and can be hard-coded.
Basically, if these values need to be configured/changed put them in Properties.Settings.Default. You can hard code constants.
personally, I use the default setting when the user or application setting are not specified or persisted.
I'd never hardcode a setting that might change based on any number of variables such as environment, user, application, or whatever.
I generally create settings providers that implement an interface. That way, you can easily change out how to gather your configuration settings without changing the business logic.
Related
I'm using the built in settings infrastructure in my Windows Phone 8.1 application to store my settings key-value pairs. For instance:
ApplicationDataContainer settings = ApplicationData.Current.LocalSettings;
object value = settings.Values["DailyReminderOnOff"];
I'm trying to find a way to supply default values that come canned with the app at installation. Is there some recommended and convenient way of doing that?
I could implement my own system by placing a dirty bit and reading from a file if it's unset or provide defaults through if-null checks within the getter; but I'd rather avoid the hassle of writing and maintaining that code if the system provides something I've missed.
Thanks!
There is no default way to get the value. Why don't you use simple fallback like this:
const string DefaultValue1 = "value123";
object value = settings.Values["DailyReminderOnOff"] ?? DefaultValue1;
I need to save a few things in the session. At the moment, I'm using InProc session on my development machine but I want to deploy using SQL server session and then Azure's AppFabric session.
I created an object that contains several properties, all primitive types. I'm handling the read of session like this:
SessionObject TheCurrentSession =
HttpContext.Current.Session["UserAppSession"] as SessionObject;
Basically, I'm wrapping session variables in an object that's serialized and deserialized each time the session loads and saves.
I'm wondering if it would be better to store each property in its native format and have the wrapping object read/save each of its properties in the session as a native type.
So for example, I'd have a method called RecreateSession like this:
public class SessionObject
{
public void RecreateSession()
{
this.SessionObjectProperty1 =
HttpContext.Current.Session["SessionObjectProperty1"];
this.SessionObjectProperty2 = ...;
this.SessionObjectProperty3 = ...;
}
}
I think doing so would prevent the serialization/deserialization process and could make the values accessible directly in other parts of the code (ie. an HTTP module).
Is it worth it to change my session implementation? What are the best practices for this?
Thanks for your suggestions.
Is it worth it to change my session implementation?
Only if it makes it easier for you to use.
What are the best practices for this?
You pretty much are already doing them. Creating a single object to hold several related properties (that are likely to be used together) and storing it in session instead of a bunch of separate session properties makes sense.
I always created a custom object in which each Property refers to a particular session item... I think its the best option.
I want to declare a variable in such a way that I can access that particular variable and its value in all the asp pages in the project. Can anyone tell me how to declare a variable in C# such that it has project-wide scope?
You have a couple of choices and the best may require more specific information about what you are trying to accomplish. For example, do you need to be able to write to this variable as well?
But a simple approach is just to store it in the application object: Application["mydata"] = value;
Note that you can lose this data if your application is reset, which can happen from time to time. You can look at using cookies or a database to persist across resets.
Declare it as a "static" variable in a static class anywhere in the projects. You can declare it either as "internal" or "public".
However, you should always be careful about such a thing. If you need this, your design might need some work.
You can use a public property in the global.asax. That way you will be able to retrieve it from anywhere in the project.
global.asax:
private string _myvar = "";
public static string MyVar{ get { return _myvar; } set { _myvar = value; } }
any page code-behind:
string text = MyClassName.Global.MyVar
Based on what you said, I supose you want some kind of global variable.
If tha's the case you should learn about the Application object and, probably, initialize your variable in the Application_Start method of global.asax file
If you need some generic approach. Create a project in your solution called Common as class library. Add a class file and add some public static members there . Compile it to dll, and you are now ready to use the members within the solution and if you wnt to use the same in some other application you can use too by adding reference.
But if you need it for some specific time you can use either of them stated above. In addition you can also use Session["MyObject"] = object_value. All have cons and pros. Google and use what ever suits you best. You have various options now, :)
Application scope defined within your global.ascx file.
Thus: Application["VariableName"] = value.
If it is user and session specific, you could always store it in a session. It's simple as: Session["VarName"] = object;
You can use the HttpContext to store items that need to be accessed throughout the lifecycle.
Example:
HttpContext.Items["myVariableKey"] = "my value";
The item put into that collection are only available for the current request.
I'm just wondering why it's Settings.Default.<mysetting> instead of just Settings.<mysetting>?
Simply put: because Settings is a class, and the properties are instance properties. So you need an instance, and the default way of creating an instance is through the Default property.
The obvious followup question is why the properties aren't just static to start with... and I surmise that the answer is that it's useful to be able to create settings in ways other than with the default settings load/save approach... for example, loading them from a database, or from a different file path.
It doesn't make sense to use Settings.Default.CompanyName when Settings.CompanyName can be created as Property returning the instance's value.
I'm starting to design a config and settings component for an application.
I need an easy way to read dictionary style settings and also a way to store simple arrays into a persistence level.
is there a commonly used component already available ? (something like log4net for logging)
what options should I look into ?
You don't really need to do that: .NET BCL already has everything you need.
Take a look at App.Config and the ConfigurationManager class.
If you expand the Properties folder in the SolutionExplorer you should find a Settings.Settings item. Double clicking on this will open the settings editor. This enables you to declare and provide initial values for settings that can either be scoped to the application or the current user. Since the values are persisted in Isolated storage you do not need to worry about what privileges the user is executing under.
For a wee example:
I created a new string setting with the name Drink and a TextBox named drinkTextBox. The code to assign the current value to the text box is:
drinkTextBox.Text = Properties.Settings.Default.Drink;
and to update the value persisted:
Properties.Settings.Default.Drink = drinkTextBox.Text;
Properties.Settings.Default.Save();
Depending on how flexible you want it to be, you can use the build in Settings designer (go to Project Properties > Settings) and you can add settings there.
These are strongly typed and accessible through code.
It has built in features like Save, Load and Reload
We'll often create a sealed class that has a number of properties that wrap calls to the the System.Configuration.ConfigurationManager class. This allows us to use the standard configuration managagement capabilities offered by the class and the app/web.config file but make the data very easy to access by other classes.
For example we might create a property to expose the connection string to a database as
public static string NorthwindConnectionString
{
get{return ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString
}
While it creates a wrapper around one line of code, which we usually try to avoid, it does make certain confiuration properties accessible via intellisense and provides some insullation around changes to the location of underlying configuration data. If we wanted to move the connection string to the registry, we could do so without major impact to the application.
We find this most helpful when we have larger teams or when we need to hand off code from one team to another. It keeps people from needing to remember what the various settings were named in the config files and even where configuration information is stored (config file, database, registry, ini file, etc.)
Building a dictionary in the standard settings
Using the standard Settings, it isn't possible to store dictionary style settings.
To emulate the System.Collections.Specialized.StringDictionary,
what I've done in the past is used two of the System.Collections.Specialized.StringCollection typed settings (this is one of your options for the setting type).
I created one called Keys, and another called values. In a class that needs these settings I've created a static constructor and looped through the two StringCollections and built the StringDictionary into a public static property. The dictionary is then available when needed.
public static StringDictionary NamedValues = new StringDictionary();
public static ClassName() // static construtor
{
StringCollection keys = Properties.Settings.Default.Keys;
StringCollection vals = Properties.Settings.Default.Values;
for(int i = 0; i < keys.Count(); i++)
{
NamedValues.Add(keys[i], vals[i]);
}
}
For noddy apps I use appSettings. For enterprise apps I usually create some custom config sections. CodeProject has some excellent articles on this.
For your scenario of key/value pairs I'd probably use something like this.