Как предоставить дополнительную информацию классу IApplicationSettingsProvider? - PullRequest
3 голосов
/ 30 апреля 2010

Возможно, раньше этот вопрос задавался по-другому, но я не смог его найти.

У меня есть одна или несколько сборок адаптера плагинов в моем приложении, например, типа IPlugin. Каждый адаптер имеет свои собственные структуры настроек, хранящиеся в общем каталоге. Хранятся ли они в одном смежном файле или в отдельных файлах, не имеет значения. Каждый адаптер может иметь одну или несколько настроек, связанных с ним. Настройки будут иметь как имя, так и плагин, для которого он будет использоваться.
Как бы я создал такую ​​систему конфигурации, используя следующие требования:

  1. Я хочу использовать встроенные .NET настройки системы и избегать записи один с нуля
  2. Хост-приложение будет ответственный за поиск плагина настройки и передать его в плагин
  3. Каждый плагин будет ответственный за чтение и письмо свои собственные настройки для разделения проблемы. Хост-приложение должен вызвать Plugin.Save (thePath) и это делает свое дело.
  4. Все настройки имеют пользовательскую область

Пока что я понимаю, что мне нужно написать свой собственный SettingsProvider, но, похоже, провайдер работает изолированно в том смысле, что невозможно передать ему такие параметры, как путь к каталогу плагина и имя настроек. Весь пример кода, который я видел, содержит провайдера, получающего данные из среды выполнения.

Ответы [ 2 ]

2 голосов
/ 02 мая 2010

Я нашел ответ, хотя и немного запутанный и требующий углубления в архитектуру .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");

В настройках SetPropertyValues ​​MySettingsProvider вы можете фактически получить данные и что-то с ними сделать:

    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();
0 голосов
/ 21 октября 2011

Плагины в вашем примере обновят PluginSettings, а затем вызовут его следующим образом:

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

}
else
{
}

Код для настроек плагина:

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

У меня была та же проблема и написал об этом.

...