有时候我们需要将一些配置对象保存到Web/App config 中,使用ConfigurationManager.GetSection()方法可以方便的从配置文件中读取信息并映射(map)成我们写好的配置对象。
<configSections> <section name="MailServerGroup" type="ConsoleApplication11.MailServerSection,ConsoleApplication11"/> </configSections> <MailServerGroup provider="www.edong.com"> <serverGroup > <mailServer client="blog.tracefact.net" address="mail2.tracefact.net" userName ="jimmyzhang" password="123456" /> <mailServer client="forum.tracefact.net" address="mail1.tracefact.net" userName ="webmaster" password="456789" /> </serverGroup> </MailServerGroup>
将配置信息映射到实体类上有两种方式,一种是继承ConfigurationSection(.NET推荐方式),另一种是实现IConfigurationSectionHandler。这里先看继承ConfigurationSection的方式如何实现。
public class MailServerSection : ConfigurationSection { [ConfigurationProperty("provider")] public string Provider { get { return this["provider"] as string; } } [ConfigurationProperty("serverGroup")] public ServerGroup ServerGroup { get { return (ServerGroup)this["serverGroup"]; } } }
这里,将配置文件中的MailServerGroup节点与MailServerSection做映射,MailServerGroup节点中的属性provider与MailServerSection类中的属性做map。MailServerGroup节点中的serverGroup与MailServerSection类中的ServerGroup做map。这里的ServerGroup是一个继承自ConfigurationElementCollection的类。
1 public class ServerGroup : ConfigurationElementCollection 2 { 3 protected override ConfigurationElement CreateNewElement() 4 { 5 return new MailServer(); 6 } 7 8 protected override object GetElementKey(ConfigurationElement element) 9 { 10 return ((MailServer)element).Client; 11 } 12 13 public override ConfigurationElementCollectionType CollectionType 14 { 15 get 16 { 17 return ConfigurationElementCollectionType.BasicMap; 18 } 19 } 20 21 protected override string ElementName 22 { 23 get 24 { 25 return "mailServer"; 26 } 27 } 28 }
而真正储存数据的是MailServer类,该类继承自ConfigurationElement
public class MailServer : ConfigurationElement { [ConfigurationProperty("client",IsKey=true)] public string Client { get { return this["client"] as string; } } [ConfigurationProperty("address")] public string Address { get { return this["address"] as string; } } [ConfigurationProperty("userName")] public string UserName { get { return this["userName"] as string; } } [ConfigurationProperty("password")] public string PassWord { get { return this["password"] as string; } } }
做好map 后,可以编写测试代码显示结果:
static void Main(string[] args) { MailServerSection mailServerSection = (MailServerSection)ConfigurationManager.GetSection("MailServerGroup"); Console.WriteLine(mailServerSection.Provider); Console.WriteLine(new string(‘-‘,20)); foreach (MailServer _mailServer in mailServerSection.ServerGroup) { Console.WriteLine(string.Format("{0}{1}{2}{3}", _mailServer.Client.PadRight(15, ‘ ‘) + Environment.NewLine, _mailServer.Address.PadRight(15, ‘ ‘) + Environment.NewLine, _mailServer.UserName.PadRight(15, ‘ ‘) + Environment.NewLine, _mailServer.PassWord.PadRight(15, ‘ ‘))); Console.WriteLine(new string(‘-‘, 20)); } PressQToExist(); }
运行结果:
现在我们在来看一下采用实现IConfigurationSectionHandler的方式获取配置信息。实现该接口需要实现Create方法。
这里我们通过轮循传入XmlNode的方式逐级获取MailServerGroup的各个节点及其属性值。传入参数section就是我们的配置节点。
1 public class MailServerGroupHandler : IConfigurationSectionHandler 2 { 3 public object Create(object parent, object configContext, XmlNode section) 4 { 5 MailServerGroup mailServerGroup = new MailServerGroup(); 6 mailServerGroup.Provider = section.Attributes["provider"].Value; 7 foreach (XmlNode _serverGroup in section.ChildNodes) 8 { 9 ServerGroup serverGroup = new ServerGroup(); 10 foreach (XmlNode _mailServer in _serverGroup.ChildNodes) 11 { 12 MailServer mailServer = new MailServer(); 13 mailServer.Client = _mailServer.Attributes["client"].Value; 14 mailServer.Address = _mailServer.Attributes["address"].Value; 15 mailServer.UserName = _mailServer.Attributes["userName"].Value; 16 mailServer.PassWord = _mailServer.Attributes["password"].Value; 17 serverGroup.MailServer.Add(mailServer); 18 } 19 mailServerGroup.ServerGroup.Add(serverGroup); 20 } 21 return mailServerGroup; 22 } 23 }
下面的各个类分别与配置文件中的各个节点进行映射map:
1 public class MailServer 2 { 3 public string Client 4 { 5 get; 6 set; 7 } 8 9 public string Address 10 { 11 get; 12 set; 13 } 14 15 public string UserName 16 { 17 get; 18 set; 19 } 20 21 public string PassWord 22 { 23 get; 24 set; 25 } 26 27 28 } 29 30 public class ServerGroup 31 { 32 public List<MailServer> MailServer 33 { 34 get; 35 set; 36 } 37 38 public ServerGroup() 39 { 40 this.MailServer = new List<MailServer>(); 41 } 42 } 43 44 public class MailServerGroup 45 { 46 public string Provider 47 { 48 get; 49 set; 50 } 51 public List<ServerGroup> ServerGroup; 52 53 public MailServerGroup() 54 { 55 this.ServerGroup = new List<ServerGroup>(); 56 } 57 }
Note: 此例中的configSections中处理配置节点的类要换成MailServerGroupHandler,如下
1 <configSections> 2 <section name="MailServerGroup" type="ConsoleApplication11.MailServerGroupHandler,ConsoleApplication11"/> 3 4 </configSections>
现在我们可以在主函数中编写测试代码了:
1 static void Main(string[] args) 2 { 3 4 MailServerGroup mailServerGroup = (MailServerGroup)ConfigurationManager.GetSection("MailServerGroup"); 5 Console.WriteLine(mailServerGroup.Provider); 6 Console.WriteLine(new string(‘-‘,20)); 7 foreach (ServerGroup _serverGroup in mailServerGroup.ServerGroup) 8 { 9 foreach (MailServer _mailServer in _serverGroup.MailServer) 10 { 11 Console.WriteLine(string.Format("{0}{1}{2}{3}", 12 _mailServer.Client.PadRight(15, ‘ ‘) + Environment.NewLine, 13 _mailServer.Address.PadRight(15, ‘ ‘) + Environment.NewLine, 14 _mailServer.UserName.PadRight(15, ‘ ‘) + Environment.NewLine, 15 _mailServer.PassWord.PadRight(15, ‘ ‘))); 16 Console.WriteLine(new string(‘-‘, 20)); 17 } 18 19 } 20 PressQToExist(); 21 } 22 23 24 static void PressQToExist() 25 { 26 Console.WriteLine("Press Q to exist."); 27 ConsoleKey key; 28 do 29 { 30 key = Console.ReadKey().Key; 31 } while (key != ConsoleKey.Q); 32 }
运行结果: