Próbuję zaimplementować sekcję konfiguracji niestandardowej w projekcie i ciągle napotykam na wyjątki, których nie rozumiem. Mam nadzieję, że ktoś może tutaj wypełnić puste miejsca.
Mam App.config
to tak:
<?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>
Mam taki ServiceConfig
element zdefiniowany:
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; }
}
}
I mam takie ServiceCollection
zdefiniowane:
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);
}
}
Brakuje mi tego, co zrobić dla przewodnika. Początkowo próbowałem zaimplementować, IConfigurationSectionHandler
ale znalazłem dwie rzeczy:
- to nie zadziałało
- jest przestarzały.
Całkowicie zagubiłem się teraz w tym, co mam zrobić, aby móc odczytać moje dane z konfiguracji. Proszę o pomoc!
c#
configuration
app-config
configuration-files
Chris Holmes
źródło
źródło
Odpowiedzi:
Poprzednia odpowiedź jest prawidłowa, ale podam Ci również cały kod.
Twój plik app.config powinien wyglądać tak:
Twoje
ServiceConfig
iServiceCollection
klasy pozostają niezmienione.Potrzebujesz nowej klasy:
I to powinno załatwić sprawę. Aby go skonsumować, możesz użyć:
źródło
[Add|Remove|Clear]ItemName
właściwości naConfigurationCollection
atrybucie nie są naprawdę konieczne w tym przypadku, ponieważ „dodać” / „clear” / „Usuń” są już nazwy domyślnych elementów XML.Jeśli szukasz sekcji konfiguracji niestandardowej, takiej jak poniżej
następnie możesz użyć mojej implementacji sekcji konfiguracji, aby rozpocząć dodawanie
System.Configuration
odwołania do zestawu do projektuSpójrz na każdy zagnieżdżony element, którego użyłem. Pierwszy to Credentials z dwoma atrybutami, więc dodajmy go najpierw
Element poświadczeń
PrimaryAgent i SecondaryAgent
Oba mają te same atrybuty i wyglądają jak adres do zestawu serwerów dla serwera podstawowego i przełączania awaryjnego, więc wystarczy utworzyć jedną klasę elementów dla obu, takich jak następujące
W dalszej części tego postu wyjaśnię, jak używać dwóch różnych elementów z jedną klasą, pomińmy SiteId, ponieważ nie ma w nim różnicy. Musisz tylko utworzyć jedną klasę, taką samą jak powyżej, z tylko jedną właściwością. zobaczmy, jak wdrożyć kolekcję Lanes
jest podzielony na dwie części, najpierw należy utworzyć klasę implementacji elementu, a następnie utworzyć klasę elementu kolekcji
LaneConfigElement
możesz zauważyć, że jeden atrybut
LanElement
jest wyliczeniem i jeśli spróbujesz użyć jakiejkolwiek innej wartości w konfiguracji, która nie jest zdefiniowana w aplikacji wyliczającej,System.Configuration.ConfigurationErrorsException
przy uruchomieniu zostanie wyrzucona . Ok, przejdźmy do definicji zbiorumożesz zauważyć, że ustawiłem,
AddItemName = "Lane"
że możesz wybrać, co chcesz dla elementu wpisu do kolekcji, wolę użyć opcji „dodaj” jako domyślną, ale zmieniłem to tylko ze względu na ten post.Teraz wszystkie nasze zagnieżdżone elementy zostały zaimplementowane, teraz powinniśmy zagregować je w klasie, która ma zostać zaimplementowana
System.Configuration.ConfigurationSection
CustomApplicationConfigSection
Teraz możesz zobaczyć, że mamy dwie właściwości o nazwie
PrimaryAgent
iSecondaryAgent
obie mają ten sam typ, teraz możesz łatwo zrozumieć, dlaczego mieliśmy tylko jedną klasę implementacji dla tych dwóch elementów.Zanim będziesz mógł użyć tej nowo wynalezionej sekcji konfiguracji w swoim app.config (lub web.config), musisz tylko powiedzieć aplikacji, że stworzyłeś własną sekcję konfiguracji i dać jej trochę szacunku, aby to zrobić musisz dodać następujące wiersze w app.config (może znajdować się zaraz po rozpoczęciu tagu głównego).
UWAGA: MyAssemblyName powinno być bez .dll, np. Jeśli nazwa pliku zestawu to myDll.dll, użyj myDll zamiast myDll.dll
aby pobrać tę konfigurację, użyj następującego wiersza kodu w dowolnym miejscu aplikacji
Mam nadzieję, że powyższy post pomoże ci zacząć od nieco skomplikowanych niestandardowych sekcji konfiguracyjnych.
Miłego kodowania :)
**** Edytuj **** Aby włączyć LINQ
LaneConfigCollection
, musisz zaimplementowaćIEnumerable<LaneConfigElement>
I dodaj następującą implementację
GetEnumerator
dla ludzi, którzy wciąż nie wiedzą, jak naprawdę działa wydajność, przeczytaj ten fajny artykuł
Dwie kluczowe kwestie zaczerpnięte z powyższego artykułu to
źródło
Oto ogólny kod do zbierania konfiguracji:
Gdy już to zrobisz
GenericConfigurationElementCollection
, możesz po prostu użyć go w sekcji konfiguracji (to jest przykład z mojego Dispatchera):Element konfiguracyjny to config tutaj:
Plik konfiguracyjny wyglądałby tak:
Mam nadzieję, że to pomoże!
źródło
Łatwiejsza alternatywa dla tych, którzy woleliby nie pisać ręcznie wszystkich tych schematów konfiguracji ...
1) Zainstaluj Nerdle.AutoConfig z NuGet
2) Zdefiniuj typ ServiceConfig (albo konkretna klasa, albo tylko interfejs)
3) Będziesz potrzebować typu do przechowywania kolekcji, np
4) Dodaj sekcję konfiguracji w ten sposób (zwróć uwagę na nazewnictwo camelCase)
5) Mapa z funkcją AutoConfig
źródło
Spróbuj dziedziczyć po ConfigurationSection . Ten post na blogu autorstwa Phila Haacka zawiera przykład.
Potwierdzono, zgodnie z dokumentacją dla IConfigurationSectionHandler :
źródło