在哪里使用Application scoop初始化Properties.Settings对象?

时间:2014-02-04 00:13:28

标签: c# properties settings nullreferenceexception

我使用Settings.settings对话框向我的项目添加了Properties > Settings文件。我创建了一个新的配置元素,其类型是自定义类型。自动生成代码的输出如下:

[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::Moslem.Model.Configuration.ApplicationConfiguration AppConfig
{
    get 
    {
        return ((global::Moslem.Model.Configuration.ApplicationConfiguration)(this["AppConfig"]));
    }
}

到目前为止,这很好。默认情况下,ApplicationScopedSettingAttribute的所有设置都是只读的。因此,我不能简单地在应用程序的其他地方启动它。显然,对ApplicationConfiguration对象的任何属性的任何使用都将抛出NullReferenceException

我的问题:

  1. 是否有标准的方法来启动具有应用范围的所有对象?
  2. 简单编写自己的构造函数并启动对象是否安全? (因为Properties.Settings自动生成为部分)

2 个答案:

答案 0 :(得分:2)

我不知道你的第二个问题的答案,但我是从数据库查询初始化设置值的方式。我认为这将与运行时通常期望的生命周期相匹配。

首先,为自动生成的设置类创建匹配的部分类实现:

[SettingsProvider(typeof(CustomSettingsProvider))]
internal sealed partial class Settings : ApplicationSettingsBase 
{
    public Settings()
    {
        CustomSettingsProvider.UpdateCustomSettings += delegate(object sender, EventArgs e)
        {
            this.Reload();
        };
    }
}

SettingsProvider属性标识作为设置源的类。

事件处理程序是可选的。如果值以异步方式更改,则可以强制设置在运行时重新加载。

以下是SettingsProvider的样子:

public partial class CustomSettingsProvider : System.Configuration.SettingsProvider, System.Configuration.IApplicationSettingsProvider
{
    // raise this event to cause the settings to be reloaded at runtime after initialization
    public static event EventHandler UpdateCustomSettings;

    public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
    {
        SettingsPropertyValueCollection result = new SettingsPropertyValueCollection();

        // the collection identifies properties to initialize
        foreach (SettingsProperty property in collection)
        {
            SettingsPropertyValue spv = new SettingsPropertyValue(property);

            // determine value...

            spv.PropertyValue = value;
            result.Add(spv);
        }

        return result;
    }
}

基类中有一些可覆盖的方法,但大部分工作都是在GetPropertyValues方法中完成的。 collection参数标识需要初始化的属性,为每个属性查找值,或提供一些默认值以避免NullReferenceExceptions。

我们正在使用此技术进行授权设置。我们在应用程序中有几个模块,每个模块都有一组不同的授权设置,但所有模块都与同一个CustomSettingsProvider绑定。

用于读取设置的数据库代码与CustomSettingsProvider类是分开的,但可通过单一界面访问CustomSettingsProvider.GetPropertyValues方法。我们在CustomSettingsProvider上添加了一个公共静态方法来引发UpdateCustomSettings事件(因为事件和方法是静态的,没有事件“sender”,但是事件参数不会被使用)。

当数据库查询完成并读入设置时,将在CustomSettingsProvider类上调用静态方法,该类会引发UpdateCustomSettings事件,而Settings类又会调用它的Reload方法。默认的Reload implmentation调用GetPropertyValues方法,使用数据库中的新数据重新初始化所有设置值。

答案 1 :(得分:1)

我找到了在应用程序启动时启动它的最快方法,但是需要从数据库重新加载值。我创建了一个带有部分类定义的新文件。我所要做的就是初始化属性隐藏字段:

namespace Application.Web.Properties
{
    public sealed partial class Settings
    {
        Settings()
        {
            this["AppConfig"] = new ApplicationConfiguration();
        }
    }
}

当我尝试以下内容时,我不再获得NullReferenceException

Properties.Settings.Default.AppConfig.PageTitle = "My Application";
Properties.Settings.Default.AppConfig.Description = "Cool Application 2014";
Properties.Settings.Default.AppConfig.Author = "Moslem © 2014";
相关问题