.NET:自定义配置节
背景
对于编译型应用程序来说,参数化程序行为是非常有必要的,.NET有其标准的配置方法,我们可以可以扩展。
示例
代码
1 using System; 2 using System.Collections; 3 using System.Text; 4 using System.Configuration; 5 using System.Xml; 6 7 namespace YEA.Infrastructure.Gateway.Config 8 { 9 public enum ExchangeType { direct, topic, fanout }; 10 public class Exchange : ConfigurationElement 11 { 12 [ConfigurationProperty("name", DefaultValue = "", IsRequired = true)] 13 public string Name 14 { 15 get { return (string) this["name"]; } 16 set { this["name"] = value; } 17 } 18 [ConfigurationProperty("connection", DefaultValue = "", IsRequired = true)] 19 public string Connection 20 { 21 get { return (string)this["connection"]; } 22 set { this["connection"] = value; } 23 } 24 [ConfigurationProperty("type", DefaultValue = "direct", IsRequired = true)] 25 public ExchangeType Type 26 { 27 get { return (ExchangeType)this["type"]; } 28 set { this["type"] = value; } 29 } 30 [ConfigurationProperty("autodelete", DefaultValue= true, IsRequired = false)] 31 public bool AutoDelete 32 { 33 get { return (bool)this["autodelete"]; } 34 set { this["autodelete"] = value; } 35 } 36 [ConfigurationProperty("durable", DefaultValue = false, IsRequired = false)] 37 public bool Durable 38 { 39 get { return (bool)this["durable"]; } 40 set { this["durable"] = value; } 41 } 42 } 43 public class ExchangeCollection : ConfigurationElementCollection 44 { 45 public override ConfigurationElementCollectionType CollectionType 46 { 47 get 48 { 49 return ConfigurationElementCollectionType.AddRemoveClearMap; 50 } 51 } 52 protected override ConfigurationElement CreateNewElement() 53 { 54 return new Exchange(); 55 } 56 protected override object GetElementKey(ConfigurationElement element) 57 { 58 return ((Exchange)element).Name; 59 } 60 public new string AddElementName 61 { 62 get { return base.AddElementName; } 63 set { base.AddElementName = value; } 64 } 65 public new string ClearElementName 66 { 67 get { return base.ClearElementName; } 68 set { base.ClearElementName = value; } 69 70 } 71 72 public new string RemoveElementName 73 { 74 get { return base.RemoveElementName; } 75 } 76 77 public new int Count 78 { 79 get { return base.Count; } 80 } 81 82 83 public Exchange this[int index] 84 { 85 get 86 { 87 return (Exchange)BaseGet(index); 88 } 89 set 90 { 91 if (BaseGet(index) != null) 92 { 93 BaseRemoveAt(index); 94 } 95 BaseAdd(index, value); 96 } 97 } 98 99 new public Exchange this[string Name] 100 { 101 get { return (Exchange)BaseGet(Name); } 102 } 103 104 public int IndexOf(Exchange exchange) 105 { 106 return BaseIndexOf(exchange); 107 } 108 109 public void Add(Exchange exchange) 110 { 111 BaseAdd(exchange); 112 // Add custom code here. 113 } 114 115 protected override void BaseAdd(ConfigurationElement element) 116 { 117 BaseAdd(element, false); 118 // Add custom code here. 119 } 120 121 public void Remove(Exchange exchange) 122 { 123 if (BaseIndexOf(exchange) >= 0) 124 BaseRemove(exchange.Name); 125 } 126 127 public void RemoveAt(int index) 128 { 129 BaseRemoveAt(index); 130 } 131 132 public void Remove(string name) 133 { 134 BaseRemove(name); 135 } 136 137 public void Clear() 138 { 139 BaseClear(); 140 // Add custom code here. 141 } 142 } 143 public class AMQPObjectsDeclarationSection : ConfigurationSection 144 { 145 [ConfigurationProperty("ExchangeList", IsDefaultCollection = false)] 146 public ExchangeCollection ExchangeList 147 { 148 get 149 { 150 ExchangeCollection exchanges = (ExchangeCollection)this["ExchangeList"]; 151 return exchanges; 152 } 153 } 154 [ConfigurationProperty("QueueList", IsDefaultCollection = false)] 155 public QueueCollection QueueList 156 { 157 get 158 { 159 QueueCollection queue = (QueueCollection)this["QueueList"]; 160 return queue; 161 } 162 } 163 [ConfigurationProperty("BindingList", IsDefaultCollection = false)] 164 public BindingCollection BindingList 165 { 166 get 167 { 168 BindingCollection binding = (BindingCollection)this["BindingList"]; 169 return binding; 170 } 171 } 172 173 protected override void DeserializeSection(System.Xml.XmlReader reader) 174 { 175 base.DeserializeSection(reader); 176 // You can add custom processing code here. 177 } 178 179 protected override string SerializeSection( 180 ConfigurationElement parentElement, 181 string name, ConfigurationSaveMode saveMode) 182 { 183 string s = 184 base.SerializeSection(parentElement, 185 name, saveMode); 186 // You can add custom processing code here. 187 return s; 188 } 189 190 } 191 }
最终XML配置
App.config
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <configSections> 4 <sectionGroup name="AMQPConnection"> 5 <section name="ConnectionSettings" 6 type="YEA.Infrastructure.Gateway.Config.ConnectionSection, YEA.Infrastructure.Gateway"></section> 7 </sectionGroup> 8 <sectionGroup name="AMQPAdmin"> 9 <section name="AMQPObjectsDeclaration" 10 type="YEA.Infrastructure.Gateway.Config.AMQPObjectsDeclarationSection, YEA.Infrastructure.Gateway" 11 allowLocation="true" 12 allowDefinition="Everywhere"></section> 13 </sectionGroup> 14 15 </configSections> 16 <AMQPConnection > 17 <ConnectionSettings configSource="Config\amqp.connection.config"/> 18 </AMQPConnection> 19 <AMQPAdmin> 20 <AMQPObjectsDeclaration configSource="Config\amqp.objects.config"/> 21 </AMQPAdmin> 22 <appSettings > 23 <add key="SleepTime" value="0"></add> 24 <!--Mode = ["Receiver","Transmitter"]--> 25 <add key="Mode" value="Receiver"></add> 26 <add key="DummyFile" value="C:\logs\YEA\Monitor\LogService.txt"></add> 27 <add key="notificationToEmail" value="ruben.rotteveel@chamberlain.com"/> 28 <add key="notificationFromEmail" value="webmaster@chamberlain.com"/> 29 </appSettings> 30 </configuration>
amqp.connection.config
1 <?xml version="1.0" encoding="utf-8" ?> 2 <ConnectionSettings> 3 <ConnectionList> 4 <add name="Connection" server="localhost" username="guest" password="guest"></add> 5 </ConnectionList> 6 <PublisherList> 7 <add name="orderPublisher" connection="Connection" exchange="orders" ></add> 8 <add name="notificationPublisher" connection="Connection" exchange="notificationExchange"></add> 9 <add name="logPublisher" connection="Connection" exchange="logExchange"></add> 10 </PublisherList> 11 <AsyncReceiverList> 12 <add name="orderReceiver" connection="Connection" queue="uk_orders, marketingemails, Accounting, CustomerService" maxthreads="40"></add> 13 <add name="notificationReceiver" connection="Connection" queue="notificationQueue" maxthreads ="1"></add> 14 <add name="logReceiver" connection="Connection" queue="logQueue" maxthreads ="1"></add> 15 </AsyncReceiverList> 16 </ConnectionSettings>
amqp.objects.config
1 <?xml version="1.0" encoding="utf-8" ?> 2 <AMQPObjectsDeclaration> 3 <ExchangeList> 4 <add name="orders" connection="Connection" type="topic" autodelete="false" durable="true"></add> 5 <add name="shipments" connection="Connection" type ="topic" autodelete="false" durable="true"></add> 6 <add name="logExchange" connection="Connection" type="topic" autodelete="false" durable="true"></add> 7 <add name="notificationExchange" connection="Connection" type="topic" autodelete="false" durable="true"></add> 8 </ExchangeList> 9 <QueueList> 10 <add name="uk_orders" connection="Connection" autodelete="false" durable="true"></add> 11 <add name="us_orders" connection="Connection" autodelete="false" durable="true"></add> 12 <add name="marketingemails" connection="Connection" autodelete ="false" durable="true"></add> 13 <add name="Accounting" connection="Connection" autodelete="false" durable="true" ></add> 14 <add name="CustomerService" connection="Connection" autodelete="false" durable="true" ></add> 15 <add name="logQueue" connection="Connection" autodelete="false" durable="true"></add> 16 <add name="notificationQueue" connection="Connection" autodelete="false" durable="true"></add> 17 </QueueList> 18 <BindingList> 19 <add queue="uk_orders" connection="Connection" exchange="orders" subscriptionkey="order.uk.#"></add> 20 <add queue="us_orders" connection="Connection" exchange="orders" subscriptionkey="order.us.#"></add> 21 <add queue="marketingemails" connection="Connection" exchange="shipments" subscriptionkey="#" ></add> 22 <add queue="marketingemails" connection="Connection" exchange="orders" subscriptionkey="#" ></add> 23 <add queue="Accounting" connection="Connection" exchange="shipments" subscriptionkey="#" ></add> 24 <add queue="Accounting" connection="Connection" exchange="orders" subscriptionkey="#" ></add> 25 <add queue="CustomerService" connection="Connection" exchange="shipments" subscriptionkey="#" ></add> 26 <add queue="CustomerService" connection="Connection" exchange="orders" subscriptionkey="#" ></add> 27 <add queue="logQueue" connection="Connection" exchange="logExchange" subscriptionkey="#"></add> 28 <add queue="notificationQueue" connection="Connection" exchange="notificationExchange" subscriptionkey="#"></add> 29 </BindingList> 30 </AMQPObjectsDeclaration>
读取配置
1 var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 2 var objects = config.GetSection("AMQPAdmin/AMQPObjectsDeclaration") as AMQPObjectsDeclarationSection;
备注
简单的使用配置并不是最好的方式,比如:在控制台程序中,最好提供两种方式:通过命令行参数和配置结合,然后采用适当的优先级处理。另外,采用JSON配置可能会更简单一点。