简体   繁体   English

C#.NET中的全局可编辑配置设置?

[英]Global editable config settings in C#.NET?

I want the best of both worlds: I want to be able to persist changes during runtime, like the User scoped application settings can, and I also want these settings to be global. 我希望两全其美:我希望能够在运行时坚持更改,就像用户范围的应用程序设置可以一样,并且我也希望这些设置是全局的。 Is there some way to accomplish this through app.config settings files? 有什么方法可以通过app.config设置文件来完成此任务吗? Should I look at some other way to persist global, runtime editable settings for my application? 我是否应该寻找其他方法来保留应用程序的全局,运行时可编辑设置?

The built in configuration manager in .Net which is used to deal with application settings in config files is read-only so technically, you can't do it using the built in libraries, however, the config file is just xml, so there's no reason why you can't just update the config file using the standard xml methods and then call .Net中用于处理配置文件中的应用程序设置的内置配置管理器是只读的,因此从技术上讲,您不能使用内置库来执行此操作,但是,配置文件只是xml,因此没有为什么不能只使用标准xml方法更新配置文件然后调用

ConfigurationManager.RefreshSection("appSettings")

when you want to reload your settings 当您想重新加载设置时

Furthermore, the OpenMappedExeConfiguration() Method of the ConfigurationManager lets you dynamically load a config file of your choosing (granted it follows the .NET xml config schema) and have your application load configuariton options from it, so you can modifcations to the file as @lomax indicated and have a common file that you can load from all your applications, using this same method. 此外,ConfigurationManager的OpenMappedExeConfiguration()方法使您可以动态加载您选择的配置文件(允许它遵循.NET xml配置模式),并让您的应用程序从中加载配置选项,因此您可以将文件修改为@ lomax已指示, 具有可使用相同方法从所有应用程序加载的公用文件。

Here's some info on OpenMappedExeConfiguration 这是一些有关OpenMappedExeConfiguration的信息

Ok, this is how I solved it: 好的,这是我解决的方法:

I created really basic ConfigurationSection , ConfigurationElement , and ConfigurationElementCollection implementations: 我创建了非常基本的ConfigurationSectionConfigurationElementConfigurationElementCollection实现:

public class CoreConfigurationSection : ConfigurationSection
{
    [ConfigurationProperty("settings", IsDefaultCollection = true)]
    [ConfigurationCollection(typeof(CoreSettingCollection), AddItemName = "setting")]
    public CoreSettingCollection Settings
    {
        get
        {
            return (CoreSettingCollection)base["settings"];
        }
    }
}

public class CoreSetting : ConfigurationElement
{
    public CoreSetting() { }

    public CoreSetting(string name, string value)
    {
        Name = name;
        Value = value;
    }

    [ConfigurationProperty("name", IsRequired = true, IsKey = true)]
    public string Name
    {
        get { return (string)this["name"]; }
        set { this["name"] = value; }
    }

    [ConfigurationProperty("value", DefaultValue = null, IsRequired = true, IsKey = false)]
    public string Value
    {
        get { return (string)this["value"]; }
        set { this["value"] = value; }
    }
}

public class CoreSettingCollection : ConfigurationElementCollection
{
    public new string this[string name]
    {
        get { return BaseGet(name) == null ? string.Empty : ((CoreSetting)BaseGet(name)).Value; }
        set { Remove(name); Add(name, value); }
    }

    public void Add(string name, string value)
    {
        if (!string.IsNullOrEmpty(value))
            BaseAdd(new CoreSetting(name, value));
    }

    public void Remove(string name)
    {
        if (BaseGet(name) != null)
            BaseRemove(name);
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new CoreSetting();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((CoreSetting)element).Name;
    }
}

And then a class to manage the configuration file: 然后是一个类来管理配置文件:

public static class Settings
{
    private static string _root { get { return "core"; } }

    private static Configuration Load()
    {
        string filename = Path.Combine(Core.BaseDirectory, "core.config");

        var mapping = new ExeConfigurationFileMap {ExeConfigFilename = filename};
        var config = ConfigurationManager.OpenMappedExeConfiguration(mapping, ConfigurationUserLevel.None);

        var section = (CoreConfigurationSection)config.GetSection(_root);

        if (section == null)
        {
            Console.Write("Core: Building core.config...");

            section = new CoreConfigurationSection();
            config.Sections.Add(_root, section);
            Defaults(section);
            config.Save(ConfigurationSaveMode.Modified);

            Console.WriteLine("done");
        }

        return config;
    }

    private static void Defaults(CoreConfigurationSection section)
    {
        section.Settings["Production"] = "false";
        section.Settings["Debug"] = "false";
        section.Settings["EventBot"] = "true";
        section.Settings["WebAccounting"] = "true";
        section.Settings["AllowPlayers"] = "true";
    }

    #region Accessors

    public static string Get(string setting)
    {
        var config = Load();
        var section = (CoreConfigurationSection)config.GetSection(_root);

        return section.Settings[setting];
    }

    public static bool GetBoolean(string setting)
    {
        var config = Load();
        var section = (CoreConfigurationSection)config.GetSection(_root);

        return section.Settings[setting].ToLower() == "true";
    }

    public static void Set(string setting,string value)
    {
        var config = Load();
        var section = (CoreConfigurationSection)config.GetSection(_root);

        if (value == null)
            section.Settings.Remove(setting);

        section.Settings[setting] = value;
        config.Save(ConfigurationSaveMode.Modified);
    }

    public static void SetBoolean(string setting, bool value)
    {
        var config = Load();
        var section = (CoreConfigurationSection)config.GetSection(_root);

        section.Settings[setting] = value.ToString();
        config.Save(ConfigurationSaveMode.Modified);
    }

    #endregion

    #region Named settings

    public static bool Production
    {
        get { return GetBoolean("Production"); }
        set { SetBoolean("Production", value); }
    }

    public static bool Debug
    {
        get { return GetBoolean("Debug"); }
        set { SetBoolean("Debug", value); }
    }

    public static bool EventBot
    {
        get { return GetBoolean("EventBot"); }
        set { SetBoolean("EventBot", value); }
    }

    public static bool WebAccounting
    {
        get { return GetBoolean("WebAccounting"); }
        set { SetBoolean("WebAccounting", value); }
    }

    public static bool AllowPlayers
    {
        get { return GetBoolean("AllowPlayers"); }
        set { SetBoolean("AllowPlayers", value); }
    }

    #endregion
}

I couldn't really think of a better way to make typed configurations than hardcoding them, but other than that it seems pretty solid to me, you can create and update configurations at runtime, they are global, editable, and located on my application root, so basically that covers all features I wanted. 除了对它们进行硬编码外,我真的没有想到一种更好的方法来进行类型化配置,但是除了对我来说看起来很扎实之外,您可以在运行时创建和更新配置,它们是全局的,可编辑的,并且位于我的应用程序根目录下,因此基本上可以涵盖我想要的所有功能。

The core.config file is created at runtime if it doesn't exist, this is verified whenever you try to load or save a setting, with some default values just to "get started"... (you can skip that "initialization" though. 如果core.config文件不存在,则会在运行时创建该文件,每当您尝试加载或保存设置时都会对其进行验证,其中一些默认值仅用于“入门” ...(您可以跳过该“初始化”虽然。

The core.config file looks like this core.config文件如下所示

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="core" type="Server.CoreConfigurationSection, ServerCore, Version=2.1.4146.38077, Culture=neutral, PublicKeyToken=null" />
    </configSections>
    <core>
        <settings>
            <setting name="Production" value="false" />
            <setting name="Debug" value="false" />
            <setting name="EventBot" value="true" />
            <setting name="WebAccounting" value="true" />
            <setting name="AllowPlayers" value="true" />
        </settings>
    </core>
</configuration>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM