Peter M
Peter M

Reputation: 7493

Programatically determine if settings is per User or per Application

Given an arbitrary settings parameter EG Properties.Settings.Default.ArbitraryParam can you tell programatically from within the application if this is a per User or per Application setting?

Alternatively, given that the per Application settings are read only, what is the best practice for protecting against attempts to write to a per Application setting? Or will nothing happen aside from the value not being updated when Properties.Settings.Default.Save() is called?

Upvotes: 0

Views: 489

Answers (1)

Ron Beyer
Ron Beyer

Reputation: 11273

If you want to determine if they are user scoped or application scoped, you can write a little extension method...

public static class SettingsExtensions
{
    public bool IsUserScoped(this Settings settings, string variableName)
    {
        PropertyInfo pi = settings.GetType().GetProperty(variableName, BindingFlags.Instance);

        return pi.GetCustomAttribute<System.Configuration.UserScopedSettingAttribute>() != null;
    }
}

Which is then called:

Settings.Default.IsUserScoped("SomeVariableName");

You can do some more tricks if you want to get the actual name from a property, but it shows one way. The other way is to determine if the property contains both a get and set accessor (user scoped) or just a get (application scoped).

This is pretty clear if you open the Settings.Designer.cs file, here is my example file:

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {

    private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

    public static Settings Default {
        get {
            return defaultInstance;
        }
    }

    [global::System.Configuration.UserScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("blah")]
    public string UserSetting {
        get {
            return ((string)(this["UserSetting"]));
        }
        set {
            this["UserSetting"] = value;
        }
    }

    [global::System.Configuration.ApplicationScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("hardy har har")]
    public string AppSetting {
        get {
            return ((string)(this["AppSetting"]));
        }
    }
}

Notice the attributes? They can be used to determine information about the properties.

However, another good way to tell is that if you write

Settings.Default.SomeAppSetting = some_value;

You will get a compiler error since there is no set accessor.

Upvotes: 1

Related Questions