Я пытаюсь реализовать пользовательский раздел конфигурации в проекте и продолжаю сталкиваться с исключениями, которые мне не понятны. Я надеюсь, что кто-то может заполнить пробелы здесь.
У меня App.config
это выглядит так:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="ServicesSection" type="RT.Core.Config.ServicesConfigurationSectionHandler, RT.Core"/>
</configSections>
<ServicesSection type="RT.Core.Config.ServicesSection, RT.Core">
<Services>
<AddService Port="6996" ReportType="File" />
<AddService Port="7001" ReportType="Other" />
</Services>
</ServicesSection>
</configuration>
У меня есть ServiceConfig
элемент, определенный так:
public class ServiceConfig : ConfigurationElement
{
public ServiceConfig() {}
public ServiceConfig(int port, string reportType)
{
Port = port;
ReportType = reportType;
}
[ConfigurationProperty("Port", DefaultValue = 0, IsRequired = true, IsKey = true)]
public int Port
{
get { return (int) this["Port"]; }
set { this["Port"] = value; }
}
[ConfigurationProperty("ReportType", DefaultValue = "File", IsRequired = true, IsKey = false)]
public string ReportType
{
get { return (string) this["ReportType"]; }
set { this["ReportType"] = value; }
}
}
И я ServiceCollection
определил, как так:
public class ServiceCollection : ConfigurationElementCollection
{
public ServiceCollection()
{
Console.WriteLine("ServiceCollection Constructor");
}
public ServiceConfig this[int index]
{
get { return (ServiceConfig)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public void Add(ServiceConfig serviceConfig)
{
BaseAdd(serviceConfig);
}
public void Clear()
{
BaseClear();
}
protected override ConfigurationElement CreateNewElement()
{
return new ServiceConfig();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ServiceConfig) element).Port;
}
public void Remove(ServiceConfig serviceConfig)
{
BaseRemove(serviceConfig.Port);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Remove(string name)
{
BaseRemove(name);
}
}
Часть, которую я пропускаю - это то, что нужно сделать для обработчика. Первоначально я пытался реализовать, IConfigurationSectionHandler
но нашел две вещи:
- это не сработало
- это устарело.
Теперь я совершенно заблудился, что делать, поэтому я могу читать свои данные из конфига. Любая помощь, пожалуйста!
c#
configuration
app-config
configuration-files
Крис Холмс
источник
источник
Ответы:
Предыдущий ответ правильный, но я дам вам весь код.
Ваш app.config должен выглядеть так:
Ваши
ServiceConfig
иServiceCollection
занятия остаются без изменений.Вам нужен новый класс:
И это должно сработать. Для его потребления вы можете использовать:
источник
[Add|Remove|Clear]ItemName
свойстваConfigurationCollection
атрибута не являются необходимыми, поскольку «add» / «clear» / «remove» уже являются именами по умолчанию элементов XML.Если вы ищете пользовательский раздел конфигурации, как показано ниже
тогда вы можете использовать мою реализацию раздела конфигурации, чтобы начать добавлять
System.Configuration
ссылку на сборку в ваш проектПосмотрите на каждый вложенный элемент, который я использовал. Первый - это Credentials с двумя атрибутами, поэтому давайте сначала добавим его.
Элемент учетных данных
PrimaryAgent и SecondaryAgent
Оба имеют одинаковые атрибуты и выглядят как адреса для набора серверов для первичного и аварийного переключения, поэтому вам просто нужно создать один класс элементов для обоих из них, таких как следующие
Позже в этом посте я объясню, как использовать два разных элемента с одним классом, давайте пропустим SiteId, поскольку в нем нет различий. Вам просто нужно создать один класс, как указано выше, только с одним свойством. давайте посмотрим, как реализовать коллекцию Lanes
он разделен на две части: сначала нужно создать класс реализации элемента, а затем создать класс элемента коллекции.
LaneConfigElement
вы можете заметить, что одним из атрибутов
LanElement
является Enumeration, и если вы попытаетесь использовать любое другое значение в конфигурации, которое не определено в приложении Enumeration,System.Configuration.ConfigurationErrorsException
при запуске будет выброшено. Хорошо, давайте перейдем к определению коллекциивы можете заметить, что я установил, что
AddItemName = "Lane"
вы можете выбрать все, что вам нравится для элемента коллекции, я предпочитаю использовать «добавить» по умолчанию, но я изменил его только ради этого поста.Теперь все наши вложенные элементы были реализованы, теперь мы должны объединить все те в классе, который должен реализовать
System.Configuration.ConfigurationSection
CustomApplicationConfigSection
Теперь вы можете видеть, что у нас есть два свойства с именем
PrimaryAgent
иSecondaryAgent
оба имеют одинаковый тип, теперь вы можете легко понять, почему у нас был только один класс реализации для этих двух элементов.Прежде чем вы сможете использовать этот недавно изобретенный раздел конфигурации в вашем app.config (или web.config), вам просто нужно сообщить приложению, что вы изобрели свой собственный раздел конфигурации и дать ему некоторое уважение, для этого вам нужно добавить следующие строки в app.config (может быть сразу после запуска корневого тега).
ПРИМЕЧАНИЕ. Имя MyAssemblyName должно быть без .dll, например, если имя файла сборки - myDll.dll, используйте myDll вместо myDll.dll.
чтобы получить эту конфигурацию, используйте следующую строку кода в любом месте вашего приложения
Надеюсь, что вышеприведенный пост поможет вам начать с немного сложного вида пользовательских разделов конфигурации.
Удачного кодирования :)
**** Редактировать **** Чтобы включить LINQ на
LaneConfigCollection
вас необходимо реализоватьIEnumerable<LaneConfigElement>
И добавить следующую реализацию
GetEnumerator
для людей, которые все еще не понимают, как действительно работает yield, прочитайте эту хорошую статью
Два ключевых пункта, взятых из вышеприведенной статьи:
источник
Это общий код для сбора конфигурации:
После этого
GenericConfigurationElementCollection
вы можете просто использовать его в разделе конфигурации (это пример из моего Dispatcher):Элемент конфигурации является config Здесь:
Файл конфигурации будет выглядеть так:
Надеюсь, это поможет!
источник
Более простая альтернатива для тех, кто предпочел бы не писать все эти шаблоны конфигурации вручную ...
1) Установите Nerdle.AutoConfig из NuGet
2) Определите ваш тип ServiceConfig (подойдет либо конкретный класс, либо просто интерфейс)
3) Вам понадобится тип для хранения коллекции, например
4) Добавьте раздел конфигурации следующим образом (обратите внимание на именование camelCase)
5) Карта с помощью AutoConfig
источник
Попробуйте наследовать от ConfigurationSection . В этом посте Фила Хаака есть пример.
Подтверждено согласно документации для IConfigurationSectionHandler :
источник