Если MyApp.PluginsConfiguration является ConfigurationSection, то вы можете определить новый класс, который наследуется от ConfigurationElementCollection, и сделать новый класс ConfigurationProperty для MyApp.PluginsConfiguration
Проверьте эту статью для получения подробной информации об этих типах. Я также написал о с вложенными свойствами, но не специально для коллекций.
Редактировать: Вот с некоторым кодом. Данный бит в файле web.config:
<configSections>
<section name="plugins"
type="WebApplication1.PluginsConfiguration, WebApplication1"/>
</configSections>
<plugins>
<use assembly="MyApp.Plugin1.dll"/>
<use assembly="MyApp.Plugin2.dll"/>
</plugins>
Вот классы, чтобы это произошло. Обратите внимание, что, возможно, есть исключения NullReferenceExceptions, которые необходимо обработать.
namespace WebApplication1
{
public class PluginsConfiguration : ConfigurationSection
{
private static ConfigurationPropertyCollection properties;
private static ConfigurationProperty propPlugins;
static PluginsConfiguration()
{
propPlugins = new ConfigurationProperty(null, typeof(PluginsElementCollection),
null,
ConfigurationPropertyOptions.IsDefaultCollection);
properties = new ConfigurationPropertyCollection { propPlugins };
}
protected override ConfigurationPropertyCollection Properties
{
get
{
return properties;
}
}
public PluginsElementCollection Plugins
{
get
{
return this[propPlugins] as PluginsElementCollection;
}
}
}
public class PluginsElementCollection : ConfigurationElementCollection
{
public PluginsElementCollection()
{
properties = new ConfigurationPropertyCollection();
}
private static ConfigurationPropertyCollection properties;
protected override ConfigurationPropertyCollection Properties
{
get
{
return properties;
}
}
public override ConfigurationElementCollectionType CollectionType
{
get
{
return ConfigurationElementCollectionType.BasicMap;
}
}
protected override string ElementName
{
get
{
return "use";
}
}
protected override ConfigurationElement CreateNewElement()
{
return new PluginsElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
var elm = element as PluginsElement;
if (elm == null) throw new ArgumentNullException();
return elm.AssemblyName;
}
}
public class PluginsElement : ConfigurationElement
{
private static ConfigurationPropertyCollection properties;
private static ConfigurationProperty propAssembly;
protected override ConfigurationPropertyCollection Properties
{
get
{
return properties;
}
}
public PluginsElement()
{
propAssembly = new ConfigurationProperty("assembly", typeof(string),
null,
ConfigurationPropertyOptions.IsKey);
properties = new ConfigurationPropertyCollection { propAssembly };
}
public PluginsElement(string assemblyName)
: this()
{
AssemblyName = assemblyName;
}
public string AssemblyName
{
get
{
return this[propAssembly] as string;
}
set
{
this[propAssembly] = value;
}
}
}
}
И чтобы получить к нему доступ, этот фрагмент кода должен помочь:
var cfg = WebConfigurationManager.GetWebApplicationSection("plugins") as PluginsConfiguration;
var sb = new StringBuilder();
foreach(PluginsElement elem in cfg.Plugins)
{
sb.AppendFormat("{0}<br/>", elem.AssemblyName);
}
testLabel.Text = sb.ToString();
По сути, у нас есть ConfigurationSection, который обрабатывает plugins-элемент. Здесь мы указываем свойство ConfigurationElementCollection и объявляем его коллекцией по умолчанию (теоретически вы можете иметь несколько разных коллекций в одном корневом узле).
PluginsElementCollection реализует ConfigurationElementCollection. ElementName должно быть именем тега, в нашем случае «use». Кроме того, GetElementKey должен быть переопределен и должен возвращать атрибут, который является уникальным среди записей.
Затем PluginsElement реализует одноразовый тег. Мы определяем только одно свойство: AssemblyName, которое сопоставляется с атрибутом assembly.
Я не утверждаю, что полностью понимаю все это (особенно ConfigurationElementCollection и его различные свойства BaseAdd, BaseGet и т. Д. Здесь на самом деле не рассматриваются), но я могу утверждать, что это работает:)
Кроме того, он не использует никаких атрибутов. Я ненавижу атрибуты - к счастью, все эти атрибуты могут быть преобразованы в правильный код. Вы можете использовать один или другой (или оба).