ApplicationSettingsBase.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Sys / System / Configuration / ApplicationSettingsBase.cs / 1305376 / ApplicationSettingsBase.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

using System.Diagnostics.CodeAnalysis; 
 
// These aren't valid violations - caused by HostProtectionAttribute.
[assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope="member", Target="System.Configuration.ApplicationSettingsBase.add_PropertyChanged(System.ComponentModel.PropertyChangedEventHandler):System.Void")] 
[assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope="member", Target="System.Configuration.ApplicationSettingsBase.remove_PropertyChanged(System.ComponentModel.PropertyChangedEventHandler):System.Void")]
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope="member", Target="System.ComponentModel.TypeDescriptor.GetConverter(System.Type):System.ComponentModel.TypeConverter")]

 
// Reviewed and found to be safe.
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope="member", Target="System.Configuration.LocalFileSettingsProvider..ctor()")] 
 
namespace System.Configuration {
 
    using System.ComponentModel;
    using System.Collections;
    using System.Diagnostics;
    using System.Reflection; 
    using System.Runtime.CompilerServices;
    using System.Security.Permissions; 
 
    /// 
    ///     Base settings class for client applications. 
    /// 
    public abstract class ApplicationSettingsBase : SettingsBase, INotifyPropertyChanged {
        private bool                            _explicitSerializeOnClass = false;
        private object[]                        _classAttributes; 
        private IComponent                      _owner;
        private PropertyChangedEventHandler     _onPropertyChanged; 
        private SettingsContext                 _context; 
        private SettingsProperty                _init;
        private SettingsPropertyCollection      _settings; 
        private SettingsProviderCollection      _providers;
        private SettingChangingEventHandler     _onSettingChanging;
        private SettingsLoadedEventHandler      _onSettingsLoaded;
        private SettingsSavingEventHandler      _onSettingsSaving; 
        private string                          _settingsKey = String.Empty;
        private bool                            _firstLoad = true; 
        private bool                            _initialized = false; 

        ///  
        ///     Default constructor without a concept of "owner" component.
        /// 
        protected ApplicationSettingsBase() : base() {
        } 

        ///  
        ///     Constructor that takes an IComponent. The IComponent acts as the "owner" of this settings class. One 
        ///     of the things we do is query the component's site to see if it has a SettingsProvider service. If it
        ///     does, we allow it to override the providers specified in the metadata. 
        /// 
        protected ApplicationSettingsBase(IComponent owner) : this(owner, String.Empty) {
        }
 
        /// 
        ///     Convenience overload that takes the settings key 
        ///  
        protected ApplicationSettingsBase(string settingsKey) {
            _settingsKey = settingsKey; 
        }

        /// 
        ///     Convenience overload that takes the owner component and settings key. 
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
        protected ApplicationSettingsBase(IComponent owner, string settingsKey) : this(settingsKey) { 
            if (owner == null) {
                throw new ArgumentNullException("owner"); 
            }

            _owner = owner;
 
            if (owner.Site != null) {
                ISettingsProviderService provSvc = owner.Site.GetService(typeof(ISettingsProviderService)) as ISettingsProviderService; 
                if (provSvc != null) { 
                    // The component's site has a settings provider service. We pass each SettingsProperty to it
                    // to see if it wants to override the current provider. 
                    foreach (SettingsProperty sp in Properties) {
                        SettingsProvider prov = provSvc.GetSettingsProvider(sp);
                        if (prov != null) {
                            sp.Provider = prov; 
                        }
                    } 
 
                    ResetProviders();
                } 
            }
        }

        ///  
        ///     The Context to pass on to the provider. Currently, this will just contain the settings group name.
        ///  
        [Browsable(false)] 
        public override SettingsContext Context {
            get { 
                if (_context == null) {
                    if (IsSynchronized) {
                        lock (this) {
                            if (_context == null) { 
                                _context = new SettingsContext();
                                EnsureInitialized(); 
                            } 
                        }
                    } 
                    else {
                        _context = new SettingsContext();
                        EnsureInitialized();
                    } 

                } 
 
                return _context;
            } 
        }

        /// 
        ///     The SettingsBase class queries this to get the collection of SettingsProperty objects. We reflect over 
        ///     the properties defined on the current object's type and use the metadata on those properties to form
        ///     this collection. 
        ///  
        [Browsable(false)]
        public override SettingsPropertyCollection Properties { 
            get {
                if (_settings == null) {
                    if (IsSynchronized) {
                        lock (this) { 
                            if (_settings == null) {
                                _settings = new SettingsPropertyCollection(); 
                                EnsureInitialized(); 
                            }
                        } 
                    }
                    else {
                        _settings = new SettingsPropertyCollection();
                        EnsureInitialized(); 
                    }
 
                } 

                return _settings; 
            }
        }

        ///  
        ///     Just overriding to add attributes.
        ///  
        [Browsable(false)] 
        public override SettingsPropertyValueCollection PropertyValues {
            get { 
                return base.PropertyValues;
            }
        }
 
        /// 
        ///     Provider collection 
        ///  
        [Browsable(false)]
        public override SettingsProviderCollection Providers { 
            get {
                if (_providers == null) {
                    if (IsSynchronized) {
                        lock (this) { 
                            if (_providers == null) {
                                _providers = new SettingsProviderCollection(); 
                                EnsureInitialized(); 
                            }
                        } 
                    }
                    else {
                        _providers = new SettingsProviderCollection();
                        EnsureInitialized(); 
                    }
                } 
 
                return _providers;
            } 
        }

        /// 
        ///     Derived classes should use this to uniquely identify separate instances of settings classes. 
        /// 
        [Browsable(false)] 
        public string SettingsKey { 
            get {
                return _settingsKey; 
            }
            set {
                _settingsKey = value;
                Context["SettingsKey"] = _settingsKey; 
            }
        } 
 
        /// 
        ///     Fires when the value of a setting is changed. (INotifyPropertyChanged implementation.) 
        /// 
        public event PropertyChangedEventHandler PropertyChanged {
            add {
                _onPropertyChanged += value; 
            }
            remove { 
                _onPropertyChanged -= value; 
            }
 
        }

        /// 
        ///     Fires when the value of a setting is about to change. This is a cancellable event. 
        /// 
        public event SettingChangingEventHandler SettingChanging { 
            add { 
                _onSettingChanging += value;
            } 
            remove {
                _onSettingChanging -= value;
            }
        } 

        ///  
        ///     Fires when settings are retrieved from a provider. It fires once for each provider. 
        /// 
        public event SettingsLoadedEventHandler SettingsLoaded { 
            add {
                _onSettingsLoaded += value;
            }
            remove { 
                _onSettingsLoaded -= value;
            } 
        } 

        ///  
        ///     Fires when Save() is called. This is a cancellable event.
        /// 
        public event SettingsSavingEventHandler SettingsSaving {
            add { 
                _onSettingsSaving += value;
            } 
            remove { 
                _onSettingsSaving -= value;
            } 
        }

        /// 
        ///     Used in conjunction with Upgrade - retrieves the previous value of a setting from the provider. 
        ///     Provider must implement IApplicationSettingsProvider to support this.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        public object GetPreviousVersion(string propertyName) {
           if (Properties.Count == 0) 
               throw new SettingsPropertyNotFoundException();

           SettingsProperty sp = Properties[propertyName];
           SettingsPropertyValue value = null; 

           if (sp == null) 
               throw new SettingsPropertyNotFoundException(); 

           IApplicationSettingsProvider clientProv = sp.Provider as IApplicationSettingsProvider; 

           if (clientProv != null) {
               value = clientProv.GetPreviousVersion(Context, sp);
           } 

           if (value != null) { 
               return value.PropertyValue; 
           }
 
           return null;
        }

        ///  
        ///     Fires the PropertyChanged event.
        ///  
        protected virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { 
            if(_onPropertyChanged != null) {
                _onPropertyChanged(this, e); 
            }
        }

        ///  
        ///     Fires the SettingChanging event.
        ///  
        protected virtual void OnSettingChanging(object sender, SettingChangingEventArgs e) { 
            if(_onSettingChanging != null) {
                _onSettingChanging(this, e); 
            }
        }

        ///  
        ///     Fires the SettingsLoaded event.
        ///  
        protected virtual void OnSettingsLoaded(object sender, SettingsLoadedEventArgs e) { 
            if(_onSettingsLoaded != null) {
                _onSettingsLoaded(this, e); 
            }
        }

        ///  
        ///     Fires the SettingsSaving event.
        ///  
        protected virtual void OnSettingsSaving(object sender, CancelEventArgs e) { 
            if(_onSettingsSaving != null) {
                _onSettingsSaving(this, e); 
            }
        }

        ///  
        ///     Causes a reload to happen on next setting access, by clearing the cached values.
        ///  
        public void Reload() { 
            if (PropertyValues != null) {
                PropertyValues.Clear(); 
            }

            foreach (SettingsProperty sp in Properties) {
                PropertyChangedEventArgs pe = new PropertyChangedEventArgs(sp.Name); 
                OnPropertyChanged(this, pe);
            } 
        } 

        ///  
        ///     Calls Reset on the providers.
        ///     Providers must implement IApplicationSettingsProvider to support this.
        /// 
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        public void Reset() {
            if (Properties != null) { 
                foreach(SettingsProvider provider in Providers) { 
                    IApplicationSettingsProvider clientProv = provider as IApplicationSettingsProvider;
                    if (clientProv != null) { 
                        clientProv.Reset(Context);
                    }
                }
            } 

            Reload(); 
        } 

        ///  
        ///     Overriden from SettingsBase to support validation event.
        /// 
        public override void Save() {
            CancelEventArgs e= new CancelEventArgs(false); 
            OnSettingsSaving(this, e);
 
            if (!e.Cancel) { 
                base.Save();
            } 
        }

        /// 
        ///     Overriden from SettingsBase to support validation event. 
        /// 
        public override object this[string propertyName] { 
            get { 
                if (IsSynchronized) {
                    lock (this) { 
                        return GetPropertyValue(propertyName);
                    }
                }
                else { 
                    return GetPropertyValue(propertyName);
                } 
 
            }
            set { 
                SettingChangingEventArgs e = new SettingChangingEventArgs(propertyName, this.GetType().FullName, SettingsKey, value, false);
                OnSettingChanging(this, e);

                if (!e.Cancel) { 
                    base[propertyName] = value;
                    // 
                    PropertyChangedEventArgs pe = new PropertyChangedEventArgs(propertyName); 
                    OnPropertyChanged(this, pe);
                } 
            }
        }

        ///  
        ///     Called when the app is upgraded so that we can instruct the providers to upgrade their settings.
        ///     Providers must implement IApplicationSettingsProvider to support this. 
        ///  
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        public virtual void Upgrade() { 
            if (Properties != null) {
                foreach(SettingsProvider provider in Providers) {
                    IApplicationSettingsProvider clientProv = provider as IApplicationSettingsProvider;
                    if (clientProv != null) { 
                        clientProv.Upgrade(Context, GetPropertiesForProvider(provider));
                    } 
                } 
            }
 
            Reload();
        }

        ///  
        ///     Creates a SettingsProperty object using the metadata on the given property
        ///     and returns it. 
        /// 
        ///     Implementation note: Initialization method - be careful not to access properties here
        ///                          to prevent stack overflow. 
        /// 
        private SettingsProperty CreateSetting(PropertyInfo propInfo) {
            object[] attributes = propInfo.GetCustomAttributes(false);
            SettingsProperty sp = new SettingsProperty(Initializer); 
            bool explicitSerialize = _explicitSerializeOnClass;
 
            sp.Name = propInfo.Name; 
            sp.PropertyType = propInfo.PropertyType;
 
            for (int i = 0; i < attributes.Length; i ++) {
                Attribute attr = attributes[i] as Attribute;
                if (attr != null) {
                    if (attr is DefaultSettingValueAttribute) { 
                        sp.DefaultValue = ((DefaultSettingValueAttribute)attr).Value;
                    } 
                    else if (attr is ReadOnlyAttribute) { 
                        sp.IsReadOnly = true;
                    } 
                    else if (attr is SettingsProviderAttribute) {
                        string providerTypeName = ((SettingsProviderAttribute)attr).ProviderTypeName;
                        Type providerType = Type.GetType(providerTypeName);
                        if (providerType != null) { 
                            SettingsProvider spdr = SecurityUtils.SecureCreateInstance(providerType) as SettingsProvider;
 
                            if (spdr != null) { 
                                spdr.Initialize(null, null);
                                spdr.ApplicationName = ConfigurationManagerInternalFactory.Instance.ExeProductName; 

                                // See if we already have a provider of the same name in our collection. If so,
                                // re-use the existing instance, since we cannot have multiple providers of the same name.
                                SettingsProvider existing = _providers[spdr.Name]; 
                                if (existing != null) {
                                    spdr = existing; 
                                } 

                                sp.Provider = spdr; 
                            }
                            else {
                                throw new ConfigurationErrorsException(SR.GetString(SR.ProviderInstantiationFailed, providerTypeName));
                            } 
                        }
                        else { 
                            throw new ConfigurationErrorsException(SR.GetString(SR.ProviderTypeLoadFailed, providerTypeName)); 
                        }
                    } 
                    else if (attr is SettingsSerializeAsAttribute) {
                        sp.SerializeAs = ((SettingsSerializeAsAttribute)attr).SerializeAs;
                        explicitSerialize = true;
                    } 
                    else {
                        // This isn't an attribute we care about, so simply pass it on 
                        // to the SettingsProvider. 
                        // NOTE: The key is the type. So if an attribute was found at class
                        //       level and also property level, the latter overrides the former 
                        //       for a given setting. This is exactly the behavior we want.

                        sp.Attributes.Add(attr.GetType(), attr);
                    } 
                }
            } 
 
            if (!explicitSerialize) {
                sp.SerializeAs = GetSerializeAs(propInfo.PropertyType); 
            }

            return sp;
 
        }
 
        ///  
        ///     Ensures this class is initialized. Initialization involves reflecting over properties and building
        ///     a list of SettingsProperty's. 
        ///
        ///     Implementation note: Initialization method - be careful not to access properties here
        ///                          to prevent stack overflow.
        ///  
        private void EnsureInitialized() {
            if (!_initialized) { 
                _initialized = true; 

                Type type = this.GetType(); 

                if (_context == null) {
                    _context = new SettingsContext();
                } 
                _context["GroupName"] = type.FullName;
                _context["SettingsKey"] = SettingsKey; 
                _context["SettingsClassType"] = type; 

                PropertyInfo[] properties = SettingsFilter(type.GetProperties(BindingFlags.Instance | BindingFlags.Public)); 
                _classAttributes = type.GetCustomAttributes(false);

                if (_settings == null) {
                    _settings = new SettingsPropertyCollection(); 
                }
 
                if (_providers == null) { 
                    _providers = new SettingsProviderCollection();
                } 

                for (int i = 0; i < properties.Length; i++) {
                    SettingsProperty sp = CreateSetting(properties[i]);
                    if (sp != null) { 
                        _settings.Add(sp);
 
                        if (sp.Provider != null && _providers[sp.Provider.Name] == null) { 
                            _providers.Add(sp.Provider);
                        } 
                    }
                }
            }
        } 

        ///  
        ///     Returns a SettingsProperty used to initialize settings. We initialize a setting with values 
        ///     derived from class level attributes, if present. Otherwise, we initialize to
        ///     reasonable defaults. 
        ///
        ///     Implementation note: Initialization method - be careful not to access properties here
        ///                          to prevent stack overflow.
        ///  
        private SettingsProperty Initializer {
            get { 
                if (_init == null) { 
                    _init = new SettingsProperty("");
                    _init.DefaultValue = null; 
                    _init.IsReadOnly = false;
                    _init.PropertyType = null;

                    SettingsProvider provider = new LocalFileSettingsProvider(); 

                    if (_classAttributes != null) { 
                        for (int i = 0; i < _classAttributes.Length; i ++) { 
                            Attribute attr = _classAttributes[i] as Attribute;
                            if (attr != null) { 
                                if (attr is ReadOnlyAttribute) {
                                    _init.IsReadOnly = true;
                                }
                                else if (attr is SettingsGroupNameAttribute) { 
                                    if (_context == null) {
                                        _context = new SettingsContext(); 
                                    } 
                                    _context["GroupName"] = ((SettingsGroupNameAttribute)attr).GroupName;
                                } 
                                else if (attr is SettingsProviderAttribute) {
                                    string providerTypeName = ((SettingsProviderAttribute)attr).ProviderTypeName;
                                    Type providerType = Type.GetType(providerTypeName);
                                    if (providerType != null) { 
                                        SettingsProvider spdr = SecurityUtils.SecureCreateInstance(providerType) as SettingsProvider;
                                        if (spdr != null) { 
                                            provider = spdr; 
                                        }
                                        else { 
                                            throw new ConfigurationErrorsException(SR.GetString(SR.ProviderInstantiationFailed, providerTypeName));
                                        }
                                    }
                                    else { 
                                        throw new ConfigurationErrorsException(SR.GetString(SR.ProviderTypeLoadFailed, providerTypeName));
                                    } 
                                } 
                                else if (attr is SettingsSerializeAsAttribute) {
                                    _init.SerializeAs = ((SettingsSerializeAsAttribute)attr).SerializeAs; 
                                    _explicitSerializeOnClass = true;
                                }
                                else {
                                    // This isn't an attribute we care about, so simply pass it on 
                                    // to the SettingsProvider.
                                    // NOTE: The key is the type. So if an attribute was found at class 
                                    //       level and also property level, the latter overrides the former 
                                    //       for a given setting. This is exactly the behavior we want.
                                    _init.Attributes.Add(attr.GetType(), attr); 
                                }
                            }
                        }
                    } 

                    //Initialize the SettingsProvider 
                    provider.Initialize(null, null); 
                    provider.ApplicationName = ConfigurationManagerInternalFactory.Instance.ExeProductName;
                    _init.Provider = provider; 

                }

                return _init; 
            }
        } 
 
        /// 
        ///     Gets all the settings properties for this provider. 
        /// 
        private SettingsPropertyCollection GetPropertiesForProvider(SettingsProvider provider) {
           SettingsPropertyCollection properties = new SettingsPropertyCollection();
           foreach (SettingsProperty sp in Properties) { 
               if (sp.Provider == provider) {
                   properties.Add(sp); 
               } 
           }
 
           return properties;
        }

        ///  
        ///     Retrieves the value of a setting. We need this method so we can fire the SettingsLoaded event
        ///     when settings are loaded from the providers.Ideally, this should be fired from SettingsBase, 
        ///     but unfortunately that will not happen in Whidbey. Instead, we check to see if the value has already 
        ///     been retrieved. If not, we fire the load event, since we expect SettingsBase to load all the settings
        ///     from this setting's provider. 
        /// 
        private object GetPropertyValue(string propertyName) {
            if (PropertyValues[propertyName] == null) {
 
                // If this is our first load and we are part of a Clickonce app, call Upgrade.
                if (_firstLoad) { 
                    _firstLoad = false; 

                    if (IsFirstRunOfClickOnceApp()) { 
                        Upgrade();
                    }
                }
 
                object temp = base[propertyName];
                SettingsProperty setting = Properties[propertyName]; 
                SettingsProvider provider = setting != null ? setting.Provider : null; 

                Debug.Assert(provider != null, "Could not determine provider from which settings were loaded"); 

                SettingsLoadedEventArgs e = new SettingsLoadedEventArgs(provider);
                OnSettingsLoaded(this, e);
 
                // Note: we need to requery the value here in case someone changed it while
                // handling SettingsLoaded. 
                return base[propertyName]; 
            }
            else { 
                return base[propertyName];
            }
        }
 
        /// 
        ///     When no explicit SerializeAs attribute is provided, this routine helps to decide how to 
        ///     serialize. 
        /// 
        private SettingsSerializeAs GetSerializeAs(Type type) { 
            //First check whether this type has a TypeConverter that can convert to/from string
            //If so, that's our first choice
            TypeConverter tc = TypeDescriptor.GetConverter(type);
            bool toString = tc.CanConvertTo(typeof(string)); 
            bool fromString = tc.CanConvertFrom(typeof(string));
            if (toString && fromString) { 
                return SettingsSerializeAs.String; 
            }
 
            //Else fallback to Xml Serialization
            return SettingsSerializeAs.Xml;
        }
 
        /// 
        ///     Returns true if this is a clickonce deployed app and this is the first run of the app 
        ///     since deployment or last upgrade. 
        /// 
        private bool IsFirstRunOfClickOnceApp() { 
            // NOTE: For perf & servicing reasons, we don't want to introduce a dependency on
            //       System.Deployment.dll here. The following code is an alternative to calling
            //       ApplicationDeployment.CurrentDeployment.IsFirstRun.
 
            // First check if the app is ClickOnce deployed
            ActivationContext actCtx = AppDomain.CurrentDomain.ActivationContext; 
 
            if (IsClickOnceDeployed(AppDomain.CurrentDomain)) {
                // Now check if this is the first run since deployment or last upgrade 
                return System.Deployment.Internal.InternalActivationContextHelper.IsFirstRun(actCtx);
            }

            return false; 
        }
 
        ///  
        ///     Returns true if this is a clickonce deployed app.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")]
        [SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.UnmanagedCode)]
        internal static bool IsClickOnceDeployed(AppDomain appDomain) { 
            // NOTE: For perf & servicing reasons, we don't want to introduce a dependency on
            //       System.Deployment.dll here. The following code is an alternative to calling 
            //       ApplicationDeployment.IsNetworkDeployed. 
            // Security Note: This is also why we need the security assert above.
 
            ActivationContext actCtx = appDomain.ActivationContext;

            // Ensures the app is running with a context from the store.
            if (actCtx != null && actCtx.Form == ActivationContext.ContextForm.StoreBounded) { 
                string fullAppId = actCtx.Identity.FullName;
                if (!String.IsNullOrEmpty(fullAppId)) { 
                    return true; 
                }
            } 

            return false;
        }
 
        /// 
        ///     Only those settings class properties that have a SettingAttribute on them are 
        ///     treated as settings. This routine filters out other properties. 
        /// 
        private PropertyInfo[] SettingsFilter(PropertyInfo[] allProps) { 
            ArrayList settingProps = new ArrayList();
            object[] attributes;
            Attribute attr;
 
            for (int i = 0; i < allProps.Length; i ++) {
                attributes = allProps[i].GetCustomAttributes(false); 
                for (int j = 0; j < attributes.Length; j ++) { 
                    attr = attributes[j] as Attribute;
                    if (attr is SettingAttribute) { 
                        settingProps.Add(allProps[i]);
                        break;
                    }
                } 
            }
 
            return (PropertyInfo[]) settingProps.ToArray(typeof(PropertyInfo)); 
        }
 
        /// 
        ///     Resets the provider collection. This needs to be called when providers change after
        ///     first being set.
        ///  
        private void ResetProviders() {
            Providers.Clear(); 
 
            foreach (SettingsProperty sp in Properties) {
                if (Providers[sp.Provider.Name] == null) { 
                    Providers.Add(sp.Provider);
                }
            }
        } 
    }
 
    ///  
    ///     Event handler for the SettingsLoaded event.
    ///  
    public delegate void SettingsLoadedEventHandler(object sender, SettingsLoadedEventArgs e);

    /// 
    ///     Event handler for the SettingsSaving event. 
    /// 
    public delegate void SettingsSavingEventHandler(object sender, CancelEventArgs e); 
 
    /// 
    ///     Event handler for the SettingChanging event. 
    /// 
    public delegate void SettingChangingEventHandler(object sender, SettingChangingEventArgs e);

    ///  
    ///     Event args for the SettingChanging event.
    ///  
    public class SettingChangingEventArgs : CancelEventArgs { 

        private string _settingClass; 
        private string _settingName;
        private string _settingKey;
        private object _newValue;
 
        public SettingChangingEventArgs(string settingName, string settingClass, string settingKey, object newValue, bool cancel) : base(cancel) {
            _settingName = settingName; 
            _settingClass = settingClass; 
            _settingKey = settingKey;
            _newValue = newValue; 
        }

        public object NewValue {
            get { 
                return _newValue;
            } 
        } 

        public string SettingClass { 
            get {
                return _settingClass;
            }
        } 

        public string SettingName { 
            get { 
                return _settingName;
            } 
        }

        public string SettingKey {
            get { 
                return _settingKey;
            } 
        } 
    }
 
    /// 
    ///     Event args for the SettingLoaded event.
    /// 
    public class SettingsLoadedEventArgs : EventArgs { 

        private SettingsProvider _provider; 
 
        public SettingsLoadedEventArgs(SettingsProvider provider) {
            _provider = provider; 
        }

        public SettingsProvider Provider {
            get { 
                return _provider;
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

using System.Diagnostics.CodeAnalysis; 
 
// These aren't valid violations - caused by HostProtectionAttribute.
[assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope="member", Target="System.Configuration.ApplicationSettingsBase.add_PropertyChanged(System.ComponentModel.PropertyChangedEventHandler):System.Void")] 
[assembly: SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Scope="member", Target="System.Configuration.ApplicationSettingsBase.remove_PropertyChanged(System.ComponentModel.PropertyChangedEventHandler):System.Void")]
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope="member", Target="System.ComponentModel.TypeDescriptor.GetConverter(System.Type):System.ComponentModel.TypeConverter")]

 
// Reviewed and found to be safe.
[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope="member", Target="System.Configuration.LocalFileSettingsProvider..ctor()")] 
 
namespace System.Configuration {
 
    using System.ComponentModel;
    using System.Collections;
    using System.Diagnostics;
    using System.Reflection; 
    using System.Runtime.CompilerServices;
    using System.Security.Permissions; 
 
    /// 
    ///     Base settings class for client applications. 
    /// 
    public abstract class ApplicationSettingsBase : SettingsBase, INotifyPropertyChanged {
        private bool                            _explicitSerializeOnClass = false;
        private object[]                        _classAttributes; 
        private IComponent                      _owner;
        private PropertyChangedEventHandler     _onPropertyChanged; 
        private SettingsContext                 _context; 
        private SettingsProperty                _init;
        private SettingsPropertyCollection      _settings; 
        private SettingsProviderCollection      _providers;
        private SettingChangingEventHandler     _onSettingChanging;
        private SettingsLoadedEventHandler      _onSettingsLoaded;
        private SettingsSavingEventHandler      _onSettingsSaving; 
        private string                          _settingsKey = String.Empty;
        private bool                            _firstLoad = true; 
        private bool                            _initialized = false; 

        ///  
        ///     Default constructor without a concept of "owner" component.
        /// 
        protected ApplicationSettingsBase() : base() {
        } 

        ///  
        ///     Constructor that takes an IComponent. The IComponent acts as the "owner" of this settings class. One 
        ///     of the things we do is query the component's site to see if it has a SettingsProvider service. If it
        ///     does, we allow it to override the providers specified in the metadata. 
        /// 
        protected ApplicationSettingsBase(IComponent owner) : this(owner, String.Empty) {
        }
 
        /// 
        ///     Convenience overload that takes the settings key 
        ///  
        protected ApplicationSettingsBase(string settingsKey) {
            _settingsKey = settingsKey; 
        }

        /// 
        ///     Convenience overload that takes the owner component and settings key. 
        /// 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
        protected ApplicationSettingsBase(IComponent owner, string settingsKey) : this(settingsKey) { 
            if (owner == null) {
                throw new ArgumentNullException("owner"); 
            }

            _owner = owner;
 
            if (owner.Site != null) {
                ISettingsProviderService provSvc = owner.Site.GetService(typeof(ISettingsProviderService)) as ISettingsProviderService; 
                if (provSvc != null) { 
                    // The component's site has a settings provider service. We pass each SettingsProperty to it
                    // to see if it wants to override the current provider. 
                    foreach (SettingsProperty sp in Properties) {
                        SettingsProvider prov = provSvc.GetSettingsProvider(sp);
                        if (prov != null) {
                            sp.Provider = prov; 
                        }
                    } 
 
                    ResetProviders();
                } 
            }
        }

        ///  
        ///     The Context to pass on to the provider. Currently, this will just contain the settings group name.
        ///  
        [Browsable(false)] 
        public override SettingsContext Context {
            get { 
                if (_context == null) {
                    if (IsSynchronized) {
                        lock (this) {
                            if (_context == null) { 
                                _context = new SettingsContext();
                                EnsureInitialized(); 
                            } 
                        }
                    } 
                    else {
                        _context = new SettingsContext();
                        EnsureInitialized();
                    } 

                } 
 
                return _context;
            } 
        }

        /// 
        ///     The SettingsBase class queries this to get the collection of SettingsProperty objects. We reflect over 
        ///     the properties defined on the current object's type and use the metadata on those properties to form
        ///     this collection. 
        ///  
        [Browsable(false)]
        public override SettingsPropertyCollection Properties { 
            get {
                if (_settings == null) {
                    if (IsSynchronized) {
                        lock (this) { 
                            if (_settings == null) {
                                _settings = new SettingsPropertyCollection(); 
                                EnsureInitialized(); 
                            }
                        } 
                    }
                    else {
                        _settings = new SettingsPropertyCollection();
                        EnsureInitialized(); 
                    }
 
                } 

                return _settings; 
            }
        }

        ///  
        ///     Just overriding to add attributes.
        ///  
        [Browsable(false)] 
        public override SettingsPropertyValueCollection PropertyValues {
            get { 
                return base.PropertyValues;
            }
        }
 
        /// 
        ///     Provider collection 
        ///  
        [Browsable(false)]
        public override SettingsProviderCollection Providers { 
            get {
                if (_providers == null) {
                    if (IsSynchronized) {
                        lock (this) { 
                            if (_providers == null) {
                                _providers = new SettingsProviderCollection(); 
                                EnsureInitialized(); 
                            }
                        } 
                    }
                    else {
                        _providers = new SettingsProviderCollection();
                        EnsureInitialized(); 
                    }
                } 
 
                return _providers;
            } 
        }

        /// 
        ///     Derived classes should use this to uniquely identify separate instances of settings classes. 
        /// 
        [Browsable(false)] 
        public string SettingsKey { 
            get {
                return _settingsKey; 
            }
            set {
                _settingsKey = value;
                Context["SettingsKey"] = _settingsKey; 
            }
        } 
 
        /// 
        ///     Fires when the value of a setting is changed. (INotifyPropertyChanged implementation.) 
        /// 
        public event PropertyChangedEventHandler PropertyChanged {
            add {
                _onPropertyChanged += value; 
            }
            remove { 
                _onPropertyChanged -= value; 
            }
 
        }

        /// 
        ///     Fires when the value of a setting is about to change. This is a cancellable event. 
        /// 
        public event SettingChangingEventHandler SettingChanging { 
            add { 
                _onSettingChanging += value;
            } 
            remove {
                _onSettingChanging -= value;
            }
        } 

        ///  
        ///     Fires when settings are retrieved from a provider. It fires once for each provider. 
        /// 
        public event SettingsLoadedEventHandler SettingsLoaded { 
            add {
                _onSettingsLoaded += value;
            }
            remove { 
                _onSettingsLoaded -= value;
            } 
        } 

        ///  
        ///     Fires when Save() is called. This is a cancellable event.
        /// 
        public event SettingsSavingEventHandler SettingsSaving {
            add { 
                _onSettingsSaving += value;
            } 
            remove { 
                _onSettingsSaving -= value;
            } 
        }

        /// 
        ///     Used in conjunction with Upgrade - retrieves the previous value of a setting from the provider. 
        ///     Provider must implement IApplicationSettingsProvider to support this.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        public object GetPreviousVersion(string propertyName) {
           if (Properties.Count == 0) 
               throw new SettingsPropertyNotFoundException();

           SettingsProperty sp = Properties[propertyName];
           SettingsPropertyValue value = null; 

           if (sp == null) 
               throw new SettingsPropertyNotFoundException(); 

           IApplicationSettingsProvider clientProv = sp.Provider as IApplicationSettingsProvider; 

           if (clientProv != null) {
               value = clientProv.GetPreviousVersion(Context, sp);
           } 

           if (value != null) { 
               return value.PropertyValue; 
           }
 
           return null;
        }

        ///  
        ///     Fires the PropertyChanged event.
        ///  
        protected virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { 
            if(_onPropertyChanged != null) {
                _onPropertyChanged(this, e); 
            }
        }

        ///  
        ///     Fires the SettingChanging event.
        ///  
        protected virtual void OnSettingChanging(object sender, SettingChangingEventArgs e) { 
            if(_onSettingChanging != null) {
                _onSettingChanging(this, e); 
            }
        }

        ///  
        ///     Fires the SettingsLoaded event.
        ///  
        protected virtual void OnSettingsLoaded(object sender, SettingsLoadedEventArgs e) { 
            if(_onSettingsLoaded != null) {
                _onSettingsLoaded(this, e); 
            }
        }

        ///  
        ///     Fires the SettingsSaving event.
        ///  
        protected virtual void OnSettingsSaving(object sender, CancelEventArgs e) { 
            if(_onSettingsSaving != null) {
                _onSettingsSaving(this, e); 
            }
        }

        ///  
        ///     Causes a reload to happen on next setting access, by clearing the cached values.
        ///  
        public void Reload() { 
            if (PropertyValues != null) {
                PropertyValues.Clear(); 
            }

            foreach (SettingsProperty sp in Properties) {
                PropertyChangedEventArgs pe = new PropertyChangedEventArgs(sp.Name); 
                OnPropertyChanged(this, pe);
            } 
        } 

        ///  
        ///     Calls Reset on the providers.
        ///     Providers must implement IApplicationSettingsProvider to support this.
        /// 
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")] 
        public void Reset() {
            if (Properties != null) { 
                foreach(SettingsProvider provider in Providers) { 
                    IApplicationSettingsProvider clientProv = provider as IApplicationSettingsProvider;
                    if (clientProv != null) { 
                        clientProv.Reset(Context);
                    }
                }
            } 

            Reload(); 
        } 

        ///  
        ///     Overriden from SettingsBase to support validation event.
        /// 
        public override void Save() {
            CancelEventArgs e= new CancelEventArgs(false); 
            OnSettingsSaving(this, e);
 
            if (!e.Cancel) { 
                base.Save();
            } 
        }

        /// 
        ///     Overriden from SettingsBase to support validation event. 
        /// 
        public override object this[string propertyName] { 
            get { 
                if (IsSynchronized) {
                    lock (this) { 
                        return GetPropertyValue(propertyName);
                    }
                }
                else { 
                    return GetPropertyValue(propertyName);
                } 
 
            }
            set { 
                SettingChangingEventArgs e = new SettingChangingEventArgs(propertyName, this.GetType().FullName, SettingsKey, value, false);
                OnSettingChanging(this, e);

                if (!e.Cancel) { 
                    base[propertyName] = value;
                    // 
                    PropertyChangedEventArgs pe = new PropertyChangedEventArgs(propertyName); 
                    OnPropertyChanged(this, pe);
                } 
            }
        }

        ///  
        ///     Called when the app is upgraded so that we can instruct the providers to upgrade their settings.
        ///     Providers must implement IApplicationSettingsProvider to support this. 
        ///  
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        public virtual void Upgrade() { 
            if (Properties != null) {
                foreach(SettingsProvider provider in Providers) {
                    IApplicationSettingsProvider clientProv = provider as IApplicationSettingsProvider;
                    if (clientProv != null) { 
                        clientProv.Upgrade(Context, GetPropertiesForProvider(provider));
                    } 
                } 
            }
 
            Reload();
        }

        ///  
        ///     Creates a SettingsProperty object using the metadata on the given property
        ///     and returns it. 
        /// 
        ///     Implementation note: Initialization method - be careful not to access properties here
        ///                          to prevent stack overflow. 
        /// 
        private SettingsProperty CreateSetting(PropertyInfo propInfo) {
            object[] attributes = propInfo.GetCustomAttributes(false);
            SettingsProperty sp = new SettingsProperty(Initializer); 
            bool explicitSerialize = _explicitSerializeOnClass;
 
            sp.Name = propInfo.Name; 
            sp.PropertyType = propInfo.PropertyType;
 
            for (int i = 0; i < attributes.Length; i ++) {
                Attribute attr = attributes[i] as Attribute;
                if (attr != null) {
                    if (attr is DefaultSettingValueAttribute) { 
                        sp.DefaultValue = ((DefaultSettingValueAttribute)attr).Value;
                    } 
                    else if (attr is ReadOnlyAttribute) { 
                        sp.IsReadOnly = true;
                    } 
                    else if (attr is SettingsProviderAttribute) {
                        string providerTypeName = ((SettingsProviderAttribute)attr).ProviderTypeName;
                        Type providerType = Type.GetType(providerTypeName);
                        if (providerType != null) { 
                            SettingsProvider spdr = SecurityUtils.SecureCreateInstance(providerType) as SettingsProvider;
 
                            if (spdr != null) { 
                                spdr.Initialize(null, null);
                                spdr.ApplicationName = ConfigurationManagerInternalFactory.Instance.ExeProductName; 

                                // See if we already have a provider of the same name in our collection. If so,
                                // re-use the existing instance, since we cannot have multiple providers of the same name.
                                SettingsProvider existing = _providers[spdr.Name]; 
                                if (existing != null) {
                                    spdr = existing; 
                                } 

                                sp.Provider = spdr; 
                            }
                            else {
                                throw new ConfigurationErrorsException(SR.GetString(SR.ProviderInstantiationFailed, providerTypeName));
                            } 
                        }
                        else { 
                            throw new ConfigurationErrorsException(SR.GetString(SR.ProviderTypeLoadFailed, providerTypeName)); 
                        }
                    } 
                    else if (attr is SettingsSerializeAsAttribute) {
                        sp.SerializeAs = ((SettingsSerializeAsAttribute)attr).SerializeAs;
                        explicitSerialize = true;
                    } 
                    else {
                        // This isn't an attribute we care about, so simply pass it on 
                        // to the SettingsProvider. 
                        // NOTE: The key is the type. So if an attribute was found at class
                        //       level and also property level, the latter overrides the former 
                        //       for a given setting. This is exactly the behavior we want.

                        sp.Attributes.Add(attr.GetType(), attr);
                    } 
                }
            } 
 
            if (!explicitSerialize) {
                sp.SerializeAs = GetSerializeAs(propInfo.PropertyType); 
            }

            return sp;
 
        }
 
        ///  
        ///     Ensures this class is initialized. Initialization involves reflecting over properties and building
        ///     a list of SettingsProperty's. 
        ///
        ///     Implementation note: Initialization method - be careful not to access properties here
        ///                          to prevent stack overflow.
        ///  
        private void EnsureInitialized() {
            if (!_initialized) { 
                _initialized = true; 

                Type type = this.GetType(); 

                if (_context == null) {
                    _context = new SettingsContext();
                } 
                _context["GroupName"] = type.FullName;
                _context["SettingsKey"] = SettingsKey; 
                _context["SettingsClassType"] = type; 

                PropertyInfo[] properties = SettingsFilter(type.GetProperties(BindingFlags.Instance | BindingFlags.Public)); 
                _classAttributes = type.GetCustomAttributes(false);

                if (_settings == null) {
                    _settings = new SettingsPropertyCollection(); 
                }
 
                if (_providers == null) { 
                    _providers = new SettingsProviderCollection();
                } 

                for (int i = 0; i < properties.Length; i++) {
                    SettingsProperty sp = CreateSetting(properties[i]);
                    if (sp != null) { 
                        _settings.Add(sp);
 
                        if (sp.Provider != null && _providers[sp.Provider.Name] == null) { 
                            _providers.Add(sp.Provider);
                        } 
                    }
                }
            }
        } 

        ///  
        ///     Returns a SettingsProperty used to initialize settings. We initialize a setting with values 
        ///     derived from class level attributes, if present. Otherwise, we initialize to
        ///     reasonable defaults. 
        ///
        ///     Implementation note: Initialization method - be careful not to access properties here
        ///                          to prevent stack overflow.
        ///  
        private SettingsProperty Initializer {
            get { 
                if (_init == null) { 
                    _init = new SettingsProperty("");
                    _init.DefaultValue = null; 
                    _init.IsReadOnly = false;
                    _init.PropertyType = null;

                    SettingsProvider provider = new LocalFileSettingsProvider(); 

                    if (_classAttributes != null) { 
                        for (int i = 0; i < _classAttributes.Length; i ++) { 
                            Attribute attr = _classAttributes[i] as Attribute;
                            if (attr != null) { 
                                if (attr is ReadOnlyAttribute) {
                                    _init.IsReadOnly = true;
                                }
                                else if (attr is SettingsGroupNameAttribute) { 
                                    if (_context == null) {
                                        _context = new SettingsContext(); 
                                    } 
                                    _context["GroupName"] = ((SettingsGroupNameAttribute)attr).GroupName;
                                } 
                                else if (attr is SettingsProviderAttribute) {
                                    string providerTypeName = ((SettingsProviderAttribute)attr).ProviderTypeName;
                                    Type providerType = Type.GetType(providerTypeName);
                                    if (providerType != null) { 
                                        SettingsProvider spdr = SecurityUtils.SecureCreateInstance(providerType) as SettingsProvider;
                                        if (spdr != null) { 
                                            provider = spdr; 
                                        }
                                        else { 
                                            throw new ConfigurationErrorsException(SR.GetString(SR.ProviderInstantiationFailed, providerTypeName));
                                        }
                                    }
                                    else { 
                                        throw new ConfigurationErrorsException(SR.GetString(SR.ProviderTypeLoadFailed, providerTypeName));
                                    } 
                                } 
                                else if (attr is SettingsSerializeAsAttribute) {
                                    _init.SerializeAs = ((SettingsSerializeAsAttribute)attr).SerializeAs; 
                                    _explicitSerializeOnClass = true;
                                }
                                else {
                                    // This isn't an attribute we care about, so simply pass it on 
                                    // to the SettingsProvider.
                                    // NOTE: The key is the type. So if an attribute was found at class 
                                    //       level and also property level, the latter overrides the former 
                                    //       for a given setting. This is exactly the behavior we want.
                                    _init.Attributes.Add(attr.GetType(), attr); 
                                }
                            }
                        }
                    } 

                    //Initialize the SettingsProvider 
                    provider.Initialize(null, null); 
                    provider.ApplicationName = ConfigurationManagerInternalFactory.Instance.ExeProductName;
                    _init.Provider = provider; 

                }

                return _init; 
            }
        } 
 
        /// 
        ///     Gets all the settings properties for this provider. 
        /// 
        private SettingsPropertyCollection GetPropertiesForProvider(SettingsProvider provider) {
           SettingsPropertyCollection properties = new SettingsPropertyCollection();
           foreach (SettingsProperty sp in Properties) { 
               if (sp.Provider == provider) {
                   properties.Add(sp); 
               } 
           }
 
           return properties;
        }

        ///  
        ///     Retrieves the value of a setting. We need this method so we can fire the SettingsLoaded event
        ///     when settings are loaded from the providers.Ideally, this should be fired from SettingsBase, 
        ///     but unfortunately that will not happen in Whidbey. Instead, we check to see if the value has already 
        ///     been retrieved. If not, we fire the load event, since we expect SettingsBase to load all the settings
        ///     from this setting's provider. 
        /// 
        private object GetPropertyValue(string propertyName) {
            if (PropertyValues[propertyName] == null) {
 
                // If this is our first load and we are part of a Clickonce app, call Upgrade.
                if (_firstLoad) { 
                    _firstLoad = false; 

                    if (IsFirstRunOfClickOnceApp()) { 
                        Upgrade();
                    }
                }
 
                object temp = base[propertyName];
                SettingsProperty setting = Properties[propertyName]; 
                SettingsProvider provider = setting != null ? setting.Provider : null; 

                Debug.Assert(provider != null, "Could not determine provider from which settings were loaded"); 

                SettingsLoadedEventArgs e = new SettingsLoadedEventArgs(provider);
                OnSettingsLoaded(this, e);
 
                // Note: we need to requery the value here in case someone changed it while
                // handling SettingsLoaded. 
                return base[propertyName]; 
            }
            else { 
                return base[propertyName];
            }
        }
 
        /// 
        ///     When no explicit SerializeAs attribute is provided, this routine helps to decide how to 
        ///     serialize. 
        /// 
        private SettingsSerializeAs GetSerializeAs(Type type) { 
            //First check whether this type has a TypeConverter that can convert to/from string
            //If so, that's our first choice
            TypeConverter tc = TypeDescriptor.GetConverter(type);
            bool toString = tc.CanConvertTo(typeof(string)); 
            bool fromString = tc.CanConvertFrom(typeof(string));
            if (toString && fromString) { 
                return SettingsSerializeAs.String; 
            }
 
            //Else fallback to Xml Serialization
            return SettingsSerializeAs.Xml;
        }
 
        /// 
        ///     Returns true if this is a clickonce deployed app and this is the first run of the app 
        ///     since deployment or last upgrade. 
        /// 
        private bool IsFirstRunOfClickOnceApp() { 
            // NOTE: For perf & servicing reasons, we don't want to introduce a dependency on
            //       System.Deployment.dll here. The following code is an alternative to calling
            //       ApplicationDeployment.CurrentDeployment.IsFirstRun.
 
            // First check if the app is ClickOnce deployed
            ActivationContext actCtx = AppDomain.CurrentDomain.ActivationContext; 
 
            if (IsClickOnceDeployed(AppDomain.CurrentDomain)) {
                // Now check if this is the first run since deployment or last upgrade 
                return System.Deployment.Internal.InternalActivationContextHelper.IsFirstRun(actCtx);
            }

            return false; 
        }
 
        ///  
        ///     Returns true if this is a clickonce deployed app.
        ///  
        [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]
        [SuppressMessage("Microsoft.Security", "CA2106:SecureAsserts")]
        [SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.UnmanagedCode)]
        internal static bool IsClickOnceDeployed(AppDomain appDomain) { 
            // NOTE: For perf & servicing reasons, we don't want to introduce a dependency on
            //       System.Deployment.dll here. The following code is an alternative to calling 
            //       ApplicationDeployment.IsNetworkDeployed. 
            // Security Note: This is also why we need the security assert above.
 
            ActivationContext actCtx = appDomain.ActivationContext;

            // Ensures the app is running with a context from the store.
            if (actCtx != null && actCtx.Form == ActivationContext.ContextForm.StoreBounded) { 
                string fullAppId = actCtx.Identity.FullName;
                if (!String.IsNullOrEmpty(fullAppId)) { 
                    return true; 
                }
            } 

            return false;
        }
 
        /// 
        ///     Only those settings class properties that have a SettingAttribute on them are 
        ///     treated as settings. This routine filters out other properties. 
        /// 
        private PropertyInfo[] SettingsFilter(PropertyInfo[] allProps) { 
            ArrayList settingProps = new ArrayList();
            object[] attributes;
            Attribute attr;
 
            for (int i = 0; i < allProps.Length; i ++) {
                attributes = allProps[i].GetCustomAttributes(false); 
                for (int j = 0; j < attributes.Length; j ++) { 
                    attr = attributes[j] as Attribute;
                    if (attr is SettingAttribute) { 
                        settingProps.Add(allProps[i]);
                        break;
                    }
                } 
            }
 
            return (PropertyInfo[]) settingProps.ToArray(typeof(PropertyInfo)); 
        }
 
        /// 
        ///     Resets the provider collection. This needs to be called when providers change after
        ///     first being set.
        ///  
        private void ResetProviders() {
            Providers.Clear(); 
 
            foreach (SettingsProperty sp in Properties) {
                if (Providers[sp.Provider.Name] == null) { 
                    Providers.Add(sp.Provider);
                }
            }
        } 
    }
 
    ///  
    ///     Event handler for the SettingsLoaded event.
    ///  
    public delegate void SettingsLoadedEventHandler(object sender, SettingsLoadedEventArgs e);

    /// 
    ///     Event handler for the SettingsSaving event. 
    /// 
    public delegate void SettingsSavingEventHandler(object sender, CancelEventArgs e); 
 
    /// 
    ///     Event handler for the SettingChanging event. 
    /// 
    public delegate void SettingChangingEventHandler(object sender, SettingChangingEventArgs e);

    ///  
    ///     Event args for the SettingChanging event.
    ///  
    public class SettingChangingEventArgs : CancelEventArgs { 

        private string _settingClass; 
        private string _settingName;
        private string _settingKey;
        private object _newValue;
 
        public SettingChangingEventArgs(string settingName, string settingClass, string settingKey, object newValue, bool cancel) : base(cancel) {
            _settingName = settingName; 
            _settingClass = settingClass; 
            _settingKey = settingKey;
            _newValue = newValue; 
        }

        public object NewValue {
            get { 
                return _newValue;
            } 
        } 

        public string SettingClass { 
            get {
                return _settingClass;
            }
        } 

        public string SettingName { 
            get { 
                return _settingName;
            } 
        }

        public string SettingKey {
            get { 
                return _settingKey;
            } 
        } 
    }
 
    /// 
    ///     Event args for the SettingLoaded event.
    /// 
    public class SettingsLoadedEventArgs : EventArgs { 

        private SettingsProvider _provider; 
 
        public SettingsLoadedEventArgs(SettingsProvider provider) {
            _provider = provider; 
        }

        public SettingsProvider Provider {
            get { 
                return _provider;
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK