如果您正在寻找如下的自定义配置部分
<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>
那么您可以使用我的“配置”部分的实现,从而开始System.Configuration
为您的项目添加程序集引用
看一下我使用的每个嵌套元素,第一个是具有两个属性的凭证,因此让我们先添加它
凭证元素
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和SecondaryAgent
两者都具有相同的属性,并且看起来像是针对主服务器和故障转移的一组服务器的地址,因此您只需为这两个服务器创建一个元素类,如下所示
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?;
}
}
}
在本文的稍后部分,我将解释如何在一个类中使用两个不同的元素,让我们跳过SiteId,因为两者之间没有区别。您只需要使用一个属性创建与上述相同的一个类。让我们看看如何实现Lanes集合
它分为两部分,首先您必须创建一个元素实现类,然后必须创建集合元素类
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
}
您会注意到的一个属性LanElement
是Enumeration,如果尝试在配置中使用在Enumeration应用程序中未定义的任何其他值,则会System.Configuration.ConfigurationErrorsException
在启动时抛出错误。好的,让我们继续前进到集合定义
[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);
}
}
您会注意到,我已经设置了,AddItemName = "Lane"
您可以为收藏夹条目选择任何您喜欢的东西,我更喜欢使用“添加”默认项,但是为了这篇文章我更改了它。
现在我们所有的嵌套元素都已实现,现在我们应该将所有这些元素汇总到一个必须实现的类中 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; }
}
}
现在您可以看到我们有两个具有名称的属性,PrimaryAgent
并且两个属性SecondaryAgent
都具有相同的类型,现在您可以轻松地理解为什么我们只有一个针对这两个元素的实现类。
在您可以在app.config(或web.config)中使用这个新发明的配置部分之前,您只需要告诉您应用程序您已经发明了自己的配置部分并给予一定的尊重,为此,您必须添加以下几行在app.config中(可能在根标记开始之后)。
<configSections>
<section name="CustomApplicationConfig" type="MyNameSpace.CustomApplicationConfigSection, MyAssemblyName" />
</configSections>
注意: MyAssemblyName应该不带.dll,例如,如果您的程序集文件名为myDll.dll,则使用myDll而不是myDll.dll
要检索此配置,请在应用程序中的任何位置使用以下代码行
CustomApplicationConfigSection config = System.Configuration.ConfigurationManager.GetSection(CustomApplicationConfigSection.SECTION_NAME) as CustomApplicationConfigSection;
我希望上面的文章可以帮助您开始使用一些复杂的自定义配置部分。
快乐编码:)
****编辑****要启用LINQ,LaneConfigCollection
您必须实现IEnumerable<LaneConfigElement>
并添加以下实现 GetEnumerator
public new IEnumerator<LaneConfigElement> GetEnumerator()
{
int count = base.Count;
for (int i = 0; i < count; i++)
{
yield return base.BaseGet(i) as LaneConfigElement;
}
}
对于仍然对收益如何真正发挥作用仍感到困惑的人们,请阅读这篇不错的文章
以上文章的两个重点是
它并没有真正结束该方法的执行。yield return会暂停方法的执行,并且在您下次调用它时(对于下一个枚举值),该方法将从上一次yield return调用继续执行。我觉得这有点令人困惑…… (谢伊·弗里德曼)
收益不是.Net运行时的功能。它只是一种C#语言功能,它由C#编译器编译成简单的IL代码。(Lars Corneliussen)