#c# #configuration #custom-configuration
#c# #конфигурация #пользовательская конфигурация
Вопрос:
Я пытаюсь создать пользовательскую конфигурацию, которая выглядит следующим образом.
<configuration>
<configSections>
<section name="actions" type="ConfigurationTest.ActionsConfig, UnitTestExperiments" />
<section name="action" type="ConfigurationTest.ActionConfig, UnitTestExperiments"/>
</configSections>
<actions poolSize="100">
<action name="a1" impl="some.class1">
<add name="key11" value="value11"/>
<add name="key12" value="key12"/>
</action>
<action name="a2" impl="some.class2">
<add name="key21" value="value21"/>
<add name="key22" value="key22"/>
</action>
</actions>
</configuration>
Здесь <action>
тег может встречаться N раз, и каждое действие будет иметь уникальный набор ключей. Я попробовал несколько разных решений и вариантов, но, похоже, я не могу правильно определить структуру / отображение классов. Я надеюсь получить структуру, которую я могу вызвать следующим образом.
using System;
using System.Configuration;
namespace ConfigurationTest
{
public class ActionsConfig : ConfigurationSection
{
[ConfigurationProperty("poolSize")]
public string PoolSize
{
get { return (string)this["poolSize"]; }
}
[ConfigurationProperty("", IsRequired = true, IsDefaultCollection = true)]
public ActionList Instances
{
get { return (ActionList)this[""]; }
set { this[""] = value; }
}
}
public class ActionList : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new ActionConfig();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ActionConfig)element).Name;
}
}
public class ActionConfig : ConfigurationSection
{
[ConfigurationProperty("name")]
public string Name
{
get { return (string)this["name"]; }
}
[ConfigurationProperty("impl")]
public string Impl
{
get { return (string)this["impl"]; }
}
[ConfigurationProperty("", IsDefaultCollection = true)]
public NameValueConfigurationCollection Settings
{
get
{
return (NameValueConfigurationCollection)base[""];
}
}
}
public class Program
{
static void Main(string[] args)
{
ActionsConfig ac = ConfigurationManager.GetSection("actions") as ActionsConfig;
Console.WriteLine(ac.PoolSize);
ActionConfig nameValueSection = ac.CurrentConfiguration.GetSection("action") as ActionConfig;
NameValueConfigurationCollection settings = nameValueSection.Settings;
foreach (var key in settings.AllKeys)
{
Console.WriteLine(settings[key].Name ": " settings[key].Value);
}
}
}
}
Трассировка исключений приведена ниже.
System.Configuration.ConfigurationErrorsException was unhandled
Message=Unrecognized element 'action'. (UnitTestExperiments.vshost.exe.Config line 8)
Source=System.Configuration
BareMessage=Unrecognized element 'action'.
Filename=UnitTestExperiments.vshost.exe.Config
Line=8
StackTrace:
at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Objectamp; result, Objectamp; resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Objectamp; result, Objectamp; resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Objectamp; result, Objectamp; resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Objectamp; result, Objectamp; resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at ConfigurationTest.Program.Main(String[] args) in C:UsersmeDocumentsVisual Studio 2010ProjectsUnitTestExperimentsProgram.cs:line 63
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Комментарии:
1. С какой именно проблемой вы столкнулись? Есть ли исключение? Можете ли вы показать определение раздела конфигурации?
2. вы нашли решение этой проблемы?
Ответ №1:
Взгляните на использование пользовательских настроек конфигурации. Это очень хороший пример.
Обновления
Пользовательские разделы ДОБАВЛЕНИЯ взгляните на пример пользовательских разделов конфигурации в файлах .NET 2.0 .config
Комментарии:
1. Я ищу структуру классов, которая позволяет мне получать доступ
<add>
к таким свойствам, как пара ключ-значение.2. Я хочу использовать
<add>
такие свойства, как пара ключ-значение, и это работает. Я не могу привязать тег Actions к N тегам действий, а затем получить доступ к свойствам, таким как пара keyvalue
Ответ №2:
Я получил ТОЧНЫЙ ответ из демонстрационного проекта здесь
Мне пришлось расширить код до дополнительного уровня, чтобы он работал на меня.