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

问题描述:

也许这个问题已经以不同的方式问过了,但我一直没能找到它。如何向IApplicationSettingsProvider类提供额外信息?

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

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

到目前为止,我意识到我需要写我自己的SettingsProvider,但供应商似乎是各自为政的,有没有办法把它传递参数,如路径插件目录的名称和设置的名称。我见过的所有示例代码都有提供者从运行时环境获取数据。

在您的示例中的插件将新了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(); 
     } 
    } 
} 

我有同样的问题和blogged关于它。

我发现了一个答案,尽管有点复杂,并且需要深入到.NET的体系结构中,但没有很好的文档记录。虽然ApplicationSettingsBase和IApplicationSettingsProvider是分离的,但是需要一点的重新耦合来完成这个工作。该解决方案涉及修改设置或您自己的定制版本,像这样:或者

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

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

,让您可以通过设置上下文更改这一类它的使用像这样前:

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

在该MySettingsProvider的设置SetPropertyValues,实际上你可以抓取的数据,并用它做什么:

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

要使用这些设置,只需INS在使用它之前tantiate类与参数化的构造函数,或者设置上下文:

 var settings = new Properties.Settings("Hello") { Setting1 = "Hello, is anyone home!" } 
     // alternative: settings.Context.Add("Name", "hello"); 
     settings.Save();