หากคุณกำลังมองหาส่วนกำหนดค่าที่กำหนดเองดังต่อไปนี้
<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
คือการแจงนับและถ้าคุณพยายามที่จะใช้ค่าอื่น ๆ ในการกำหนดค่าซึ่งไม่ได้กำหนดไว้ในการประยุกต์ใช้การแจงนับจะโยน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;
ฉันหวังว่าโพสต์ด้านบนจะช่วยให้คุณเริ่มต้นใช้งานส่วนกำหนดค่าแบบกำหนดเองที่ซับซ้อนเล็กน้อย
Happy Coding :)
**** แก้ไข **** เพื่อเปิดใช้งาน 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;
}
}
สำหรับผู้ที่ยังคงสับสนเกี่ยวกับวิธีการทำงานได้จริงอ่านบทความดีนี้
ประเด็นสำคัญสองข้อที่นำมาจากบทความข้างต้นคือ
มันไม่ได้จบการทำงานของวิธีการจริงๆ คืนผลตอบแทนหยุดการดำเนินการวิธีการและในครั้งต่อไปที่คุณเรียกมัน (สำหรับค่าการแจงนับต่อไป) วิธีการจะดำเนินการต่อไปจากการเรียกผลตอบแทนผลตอบแทนที่ผ่านมา ฟังดูสับสนเล็กน้อยที่ฉันคิดว่า… (Shay Friedman)
ผลตอบแทนไม่ได้เป็นคุณสมบัติของรันไทม์. Net มันเป็นเพียงคุณสมบัติภาษา C # ซึ่งได้รับการรวบรวมเป็นรหัส IL ง่ายโดยคอมไพเลอร์ C # (Lars Corneliussen)