Monday, January 3, 2011

Implementing System.Configuration.SettingsProvider

I wanted to store all settings for an application as user settings so my app wouldn't writing to the app.config and require administrative privileges.  I struggled figuring out how the components in System.Configuration worked together, but luckily Reflector, Visual Studio's .NET Framework Source debugging, ProcessMonitor, MSDN articles, StackOverflow posts, and Code Project articles helped get my scenario working.

During this process I learned the SettingsProvider only handles retrieving and saving values to the datastore and how to implement one.  I didn't end up using it since the LocalFileSettingsProvider met my needs, but the code below is a good starting point for someone wanting to implement settings persistence in a different manner:

using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Diagnostics;
 
public sealed class CustomettingsProvider : SettingsProviderIApplicationSettingsProvider
{
    NameValueCollection settingValues = new NameValueCollection();
 
    public override void Initialize(string name, NameValueCollection config)
    {
        Debug.WriteLine("in initialize override");
        base.Initialize(this.ApplicationName, settingValues);
    }
 
    /// <summary>
    /// MSDN states this property should be implemented with this getter and a do nothing setter.
    /// </summary>
    public override string ApplicationName
    {
        get  {  return (System.Reflection.Assembly.GetExecutingAssembly().GetName().Name); }
        set { Debug.WriteLine("set application name called"); }
    }
 
    public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
    {
        SettingsPropertyValueCollection returnValue = new SettingsPropertyValueCollection();
        foreach (SettingsProperty item in collection)
        {
            SettingsPropertyValue addMe = new SettingsPropertyValue(item);
            addMe.PropertyValue = String.Empty;
            returnValue.Add(addMe);
        }
 
        return returnValue;
    }
 
    public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
    {
        Debug.WriteLine("in setPropertyValues");
 
        foreach (SettingsPropertyValue item in collection)
        {
            bool isUserScoped = (item.Property.Attributes[typeof(UserScopedSettingAttribute)] is UserScopedSettingAttribute);
            bool isAppScoped = (item.Property.Attributes[typeof(ApplicationScopedSettingAttribute)] is ApplicationScopedSettingAttribute);
            if (isUserScoped && isAppScoped)
            {
                throw new ConfigurationErrorsException("Property can't be userScoped and appScoped according to msdn: http://msdn.microsoft.com/en-us/library/system.configuration.settingsprovider(VS.80).aspx");
            }
        }
    }
 
    public SettingsPropertyValue GetPreviousVersion(SettingsContext context, SettingsProperty property)
    {
        Debug.WriteLine("in getPreviousVersion");
        throw new NotSupportedException("Get Previous Version is not supported");
    }
 
    public void Reset(SettingsContext context)
    {
        Debug.WriteLine("in Reset");
    }
 
    public void Upgrade(SettingsContext context, SettingsPropertyCollection properties)
    {
        Debug.WriteLine("in Upgrade");
    }
}

No comments: