Как предоставить дополнительную информацию классу IApplicationSettingsProvider?
Возможно, раньше этот вопрос задавался по-другому, но я не смог его найти.
У меня есть одна или несколько сборок адаптера плагинов в моем приложении, например, все имеют тип IPlugin. Каждый адаптер имеет свои собственные структуры настроек, хранящиеся в общем каталоге. Хранятся ли они в одном смежном файле или в отдельных файлах, не имеет значения. Каждый адаптер может иметь одну или несколько настроек, связанных с ним. Настройки будут иметь как имя, так и плагин, для которого он будет использоваться.
Как бы я создал такую систему конфигурации, используя следующие требования:
- Я хочу использовать.NET встроенную систему настроек и не писать с нуля
- Хост-приложение будет отвечать за определение настроек плагина и передачу его плагину.
- Каждый плагин будет отвечать за чтение и запись своих настроек, чтобы разделить проблемы. Хост-приложение должно вызвать Plugin.Save (thePath), и оно делает свое дело.
- Все настройки доступны пользователю
Пока что я понимаю, что мне нужно написать свой собственный SettingsProvider, но поставщик, кажется, работает изолированно, поскольку нет способа передать ему такие параметры, как путь к каталогу плагина и имя настроек. Весь пример кода, который я видел, имеет провайдера, получающего данные из среды выполнения.
2 ответа
Плагины в вашем примере будут новые 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();
}
}
}
Я нашел ответ, хотя и немного запутанный и требующий углубления в архитектуру.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();