Jeśli szukasz sekcji konfiguracji niestandardowej, takiej jak poniżej
<CustomApplicationConfig>
<Credentials Username="itsme" Password="mypassword"/>
<PrimaryAgent Address="10.5.64.26" Port="3560"/>
<SecondaryAgent Address="10.5.64.7" Port="3570"/>
<Site Id="123" />
<Lanes>
<Lane Id="1" PointId="north" Direction="Entry"/>
<Lane Id="2" PointId="south" Direction="Exit"/>
</Lanes>
</CustomApplicationConfig>
następnie możesz użyć mojej implementacji sekcji konfiguracji, aby rozpocząć dodawanie System.Configuration
odwołania do zestawu do projektu
Spó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ń
public class CredentialsConfigElement : System.Configuration.ConfigurationElement
{
[ConfigurationProperty("Username")]
public string Username
{
get
{
return base["Username"] as string;
}
}
[ConfigurationProperty("Password")]
public string Password
{
get
{
return base["Password"] as string;
}
}
}
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
public class ServerInfoConfigElement : ConfigurationElement
{
[ConfigurationProperty("Address")]
public string Address
{
get
{
return base["Address"] as string;
}
}
[ConfigurationProperty("Port")]
public int? Port
{
get
{
return base["Port"] as int?;
}
}
}
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
public class LaneConfigElement : ConfigurationElement
{
[ConfigurationProperty("Id")]
public string Id
{
get
{
return base["Id"] as string;
}
}
[ConfigurationProperty("PointId")]
public string PointId
{
get
{
return base["PointId"] as string;
}
}
[ConfigurationProperty("Direction")]
public Direction? Direction
{
get
{
return base["Direction"] as Direction?;
}
}
}
public enum Direction
{
Entry,
Exit
}
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 zbioru
[ConfigurationCollection(typeof(LaneConfigElement), AddItemName = "Lane", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class LaneConfigCollection : ConfigurationElementCollection
{
public LaneConfigElement this[int index]
{
get { return (LaneConfigElement)BaseGet(index); }
set
{
if (BaseGet(index) != null)
{
BaseRemoveAt(index);
}
BaseAdd(index, value);
}
}
public void Add(LaneConfigElement serviceConfig)
{
BaseAdd(serviceConfig);
}
public void Clear()
{
BaseClear();
}
protected override ConfigurationElement CreateNewElement()
{
return new LaneConfigElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((LaneConfigElement)element).Id;
}
public void Remove(LaneConfigElement serviceConfig)
{
BaseRemove(serviceConfig.Id);
}
public void RemoveAt(int index)
{
BaseRemoveAt(index);
}
public void Remove(String name)
{
BaseRemove(name);
}
}
moż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
public class CustomApplicationConfigSection : System.Configuration.ConfigurationSection
{
private static readonly ILog log = LogManager.GetLogger(typeof(CustomApplicationConfigSection));
public const string SECTION_NAME = "CustomApplicationConfig";
[ConfigurationProperty("Credentials")]
public CredentialsConfigElement Credentials
{
get
{
return base["Credentials"] as CredentialsConfigElement;
}
}
[ConfigurationProperty("PrimaryAgent")]
public ServerInfoConfigElement PrimaryAgent
{
get
{
return base["PrimaryAgent"] as ServerInfoConfigElement;
}
}
[ConfigurationProperty("SecondaryAgent")]
public ServerInfoConfigElement SecondaryAgent
{
get
{
return base["SecondaryAgent"] as ServerInfoConfigElement;
}
}
[ConfigurationProperty("Site")]
public SiteConfigElement Site
{
get
{
return base["Site"] as SiteConfigElement;
}
}
[ConfigurationProperty("Lanes")]
public LaneConfigCollection Lanes
{
get { return base["Lanes"] as LaneConfigCollection; }
}
}
Teraz możesz zobaczyć, że mamy dwie właściwości o nazwie PrimaryAgent
i SecondaryAgent
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).
<configSections>
<section name="CustomApplicationConfig" type="MyNameSpace.CustomApplicationConfigSection, MyAssemblyName" />
</configSections>
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
CustomApplicationConfigSection config = System.Configuration.ConfigurationManager.GetSection(CustomApplicationConfigSection.SECTION_NAME) as CustomApplicationConfigSection;
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
public new IEnumerator<LaneConfigElement> GetEnumerator()
{
int count = base.Count;
for (int i = 0; i < count; i++)
{
yield return base.BaseGet(i) as LaneConfigElement;
}
}
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
tak naprawdę nie kończy wykonywania metody. yield return wstrzymuje wykonywanie metody, a przy następnym wywołaniu jej (dla następnej wartości wyliczenia) metoda będzie nadal wykonywana od ostatniego wywołania funkcji yield return. Wydaje mi się, że to trochę zagmatwane… (Shay Friedman)
Wydajność nie jest cechą środowiska wykonawczego .Net. Jest to po prostu funkcja języka C #, która jest kompilowana do prostego kodu IL przez kompilator C #. (Lars Corneliussen)