如何向 IApplicationSettingsProvider 类提供额外信息?

发布于 2024-08-30 13:31:11 字数 523 浏览 1 评论 0原文

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

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

  1. 我想使用内置的.NET 设置系统并避免写入 从头开始
  2. 主机应用程序将是 负责定位插件 设置并将其传递给 插件
  3. 每个插件都会 负责阅读和写作 自己的设置来分开 的担忧。主机应用程序 应该调用 Plugin.Save(thePath) 并 它做它的事。
  4. 所有设置都是用户范围的

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

Perhaps this question has been asked before in a different way, but I haven’t been able to find it.

I have one or more plugin adapter assemblies in my application all having the type IPlugin, for instance. Each adapter has its own settings structures stored in a common directory. Whether they are stored in one contiguous file or in separate ones doesn’t matter. Each adapter can have one or more settings associated with it. The settings will have both a name and the Plugin it will be used for.
How would I create such a configuration system using the following requirements:

  1. I want to use .NETs built in
    settings system and avoid writing
    one from scratch
  2. The host application will be
    responsible for locating the plugin
    settings and passing it to the
    plugin
  3. Each plugin will be
    responsible for reading and writing
    its own settings to separate
    concerns. The host application
    should call Plugin.Save(thePath) and
    it does its thing.
  4. All settings are user scoped

So far, I realize that I would need to write my own SettingsProvider, but the provider seems to work in isolation in that there’s no way to pass it parameters such as the path of the plugin directory and the name of the settings. All of the example code I've seen has the provider getting the data from the runtime environment.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

罪#恶を代价 2024-09-06 13:31:11

我找到了一个答案,尽管有点复杂,并且需要深入研究 .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();

I found an answer albeit a bit convoluted and requires going deep into the architecture of .NET, which isn't well documented. Although ApplicationSettingsBase and IApplicationSettingsProvider are decoupled, there is a bit of recoupling involved to make this work. The solution involves modifying the Settings or your own customized version like so:

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

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

Alternatively, you can get around making changes to this class by setting the Context before it's used like so:

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

In the settings SetPropertyValues of the MySettingsProvider, you can actually grab the data and do something with it:

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

To use the settings, simply instantiate the class with the parametrized constructor, or alternatively set the Context before using it:

        var settings = new Properties.Settings("Hello") { Setting1 = "Hello, is anyone home!" }
        // alternative: settings.Context.Add("Name", "hello");
        settings.Save();
倾`听者〃 2024-09-06 13:31:11

您示例中的插件将新建一个 PluginSettings ,然后像这样调用它:

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();
        }
    }
}

我遇到了同样的问题,并且 博客关于它。

The plugins in your example would new up a PluginSettings and then call into it like this:

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

}
else
{
}

Code for 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();
        }
    }
}

I had the same issue and blogged about it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文