Próbuję napisać bardzo prostą sekcję konfiguracji niestandardowej dla aplikacji .NET4. Moim celem jest to:Prosta niestandardowa sekcja konfiguracji z kolekcją w .NET4
<configuration>
<configSections>
<section name="myServices" type="My.ConfigSection, My.Assembly" />
</configSections>
<myServices>
<add name="First" />
<add name="Second" />
</myServices>
</configuration>
Ja jednak zachować coraz ConfigurationErrorsException
: „elementu Nierozpoznany«Dodaj»” gdy zgłoszę ConfigurationManager.GetSection("myServices")
. Wpatrywałam się w to od jakiegoś czasu, ale nie zrozumiałam jeszcze, co robię źle. Poniżej znajduje się mój kod. To trzy klasy: ConfigSection
, MyServiceSettingsCollection
i MyServiceSettings
.
Najpierw klasa reprezentująca całą sekcję konfiguracji. Ma bezimienną domyślną kolekcję typu MyServiceSettingsCollection
. Właściwość IsDefaultCollection
powinna umożliwić mi "dodanie" bezpośrednio do mojej kolekcji z elementu głównego.
public sealed class ConfigSection : ConfigurationSection
{
private static readonly ConfigurationProperty _propMyServices;
private static readonly ConfigurationPropertyCollection _properties;
public static ConfigSection Instance { get { return _instance; } }
static ConfigSection()
{
_propMyServices = new ConfigurationProperty(
null, typeof(MyServiceSettingsCollection), null,
ConfigurationPropertyOptions.IsDefaultCollection);
_properties = new ConfigurationPropertyCollection { _propMyServices };
}
[ConfigurationProperty("", IsDefaultCollection = true)]
public MyServiceSettingsCollection MyServices
{
get { return (MyServiceSettingsCollection) base[_propMyServices]; }
set { base[_propMyServices] = value; }
}
protected override ConfigurationPropertyCollection Properties
{ get { return _properties; } }
}
Następnie sama klasa kolekcji. Jest to typ AddRemoveClearMap
.
[ConfigurationCollection(typeof(MyServiceSettings),
CollectionType = ConfigurationElementCollectionType.AddRemoveClearMap)]
public sealed class MyServiceSettingsCollection : ConfigurationElementCollection
{
public MyServiceSettings this[int index]
{
get { return (MyServiceSettings) BaseGet(index); }
set
{
if (BaseGet(index) != null) { BaseRemoveAt(index); }
BaseAdd(index, value);
}
}
public new MyServiceSettings this[string key]
{
get { return (MyServiceSettings) BaseGet(key); }
}
protected override ConfigurationElement CreateNewElement()
{
return new MyServiceSettings();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((MyServiceSettings) element).Key;
}
}
I wreszcie klasa dla elementów w kolekcji. Na razie ta klasa ma jedną właściwość, ale będzie później (co powstrzymuje mnie przed użyciem NameValueSectionHandler
).
public class MyServiceSettings : ConfigurationElement
{
private static readonly ConfigurationProperty _propName;
private static readonly ConfigurationPropertyCollection properties;
static MyServiceSettings()
{
_propName = new ConfigurationProperty("name", typeof(string), null, null,
new StringValidator(1),
ConfigurationPropertyOptions.IsRequired |
ConfigurationPropertyOptions.IsKey);
properties = new ConfigurationPropertyCollection { _propName };
}
[ConfigurationProperty("name", DefaultValue = "",
Options = ConfigurationPropertyOptions.IsRequired |
ConfigurationPropertyOptions.IsKey)]
public string Name
{
get { return (string) base[_propKey]; }
set { base[_propKey] = value; }
}
protected override ConfigurationPropertyCollection Properties
{ get { return properties; } }
}
ale dobrze wiedzieć jak to działa - będzie miało coś podobnego do osiągnięcia w ciągu najbliższych tygodni, więc dzięki :-) – Yahia
To dziwne. Zarówno 'IsDefaultCollection' jak i' Options' działają dla mnie. Ale posiadanie pustego łańcucha nazwy właściwości wydaje się obowiązkowe. –
Patrząc na źródło referencyjne dla właściwości ConfigurationPropertyAttribute.cs, właściwość IsDefaultCollection jest tylko opakowaniem w opcji właściwości flags - http://referencesource.microsoft.com/#System.Configuration/System/Configuration/ConfigurationPropertyAttribute.cs,62 –