3

也许这个问题以前以不同的方式被问过,但我一直没能找到它。

例如,我的应用程序中有一个或多个插件适配器程序集都具有 IPlugin 类型。每个适配器都有自己的设置结构存储在一个公共目录中。它们是存储在一个连续的文件中还是单独的文件中并不重要。每个适配器都可以有一个或多个与之关联的设置。这些设置将具有名称和将用于的插件。
我将如何使用以下要求创建这样的配置系统:

  1. 我想使用 .NET 内置的设置系统,避免从头开始编写
  2. 宿主应用程序将负责定位插件设置并将其传递给插件
  3. 每个插件将负责读取和写入自己的设置以分离关注点。宿主应用程序应该调用 Plugin.Save(thePath) 并且它会做它的事情。
  4. 所有设置都是用户范围的

到目前为止,我意识到我需要编写自己的 SettingsProvider,但提供程序似乎是孤立地工作的,因为无法向它传递参数,例如插件目录的路径和设置的名称。我见过的所有示例代码都有提供者从运行时环境中获取数据。

4

2 回答 2

2

我找到了一个答案,尽管有点令人费解,并且需要深入研究 .NET 的体系结构,但没有很好的文档记录。尽管 ApplicationSettingsBase 和 IApplicationSettingsProvider 是解耦的,但要完成这项工作需要进行一些重新耦合。该解决方案涉及修改设置或您自己的自定义版本,如下所示:

[SettingsProvider(typeof(CustomSettingProviders.MySettingsProvider))]
internal sealed partial class Settings {

    public Settings(string name)
    {
         this.Context.Add("Name", name);
    }

或者,您可以通过在使用之前设置 Context 来绕过对此类进行更改,如下所示:

        settings.Context.Add("Name", "hello");

在 MySettingsProvider 的设置 SetPropertyValues 中,您实际上可以抓取数据并对其进行处理:

    public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
    {
        if (context.Contains("Name"))
            ApplicationName = context["Name"].ToString();

要使用这些设置,只需使用参数化构造函数实例化类,或者在使用之前设置 Context:

        var settings = new Properties.Settings("Hello") { Setting1 = "Hello, is anyone home!" }
        // alternative: settings.Context.Add("Name", "hello");
        settings.Save();
于 2010-05-02T02:15:14.397 回答
0

您示例中的插件将新建 aPluginSettings然后像这样调用它:

PluginSettings["age"] = "5";
int age;
if (int.TryParse(PluginSettings["age"], out age)
{

}
else
{
}

PluginSettings 的代码:

using System.Configuration;
using System.Xml;

public sealed class PluginSettings
{
    public string this[string propertyName]
    {
        get
        {
            var store = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
            UserSettingsGroup values = (UserSettingsGroup)store.SectionGroups["userSettings"];
            if (values == null)
            {
                return null;
            }
            ClientSettingsSection myValues = (ClientSettingsSection)values.Sections[typeof(DebuggerSettings).FullName];
            if (myValues == null)
            {
                return null;
            }
            SettingElement setting = myValues.Settings.Get(propertyName);
            if (setting == null)
            {
                return null;
            }
            string returnValue = setting.Value.ValueXml.InnerText;
            return returnValue;
        }
        set
        {
            var store = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
            UserSettingsGroup addSectionGroup = (UserSettingsGroup)store.SectionGroups["userSettings"];
            if (addSectionGroup == null)
            {
                addSectionGroup = new UserSettingsGroup();
                store.SectionGroups.Add("userSettings",addSectionGroup);
            }
            string sectionName = (typeof(DebuggerSettings).FullName);
            ClientSettingsSection clientSettingsSection = (ClientSettingsSection)addSectionGroup.Sections[sectionName];
            if (clientSettingsSection == null)
            {
                clientSettingsSection = new ClientSettingsSection();
                clientSettingsSection.SectionInformation.AllowExeDefinition = ConfigurationAllowExeDefinition.MachineToLocalUser;
                addSectionGroup.Sections.Add(sectionName, clientSettingsSection);
            }
            SettingElement addMe = new SettingElement(propertyName, SettingsSerializeAs.String);
            XmlElement element = new XmlDocument().CreateElement("value");
            element.InnerText = value;
            addMe.Value.ValueXml = element;
            clientSettingsSection.Settings.Add(addMe);

            store.Save();
        }
    }
}

我有同样的问题并在博客上写了。

于 2011-10-21T10:10:31.307 回答