技术开发 频道

.NET项目:XML配置文件的另类读取方式

  【IT168技术】昨天看到博客园的Fish Li博友写了一篇关于在.net中读写config文件的各种基本方法,甚是不错,本着与大家分享学习的目的,现把我们项目中对XML格式基础配置文件的读取类与大家分享一下,希望对大家有所帮助。

  FileWatcher的特点

  通用类的名称为FileWatcher,主要特点如下:

  ①使用泛型以便能够读取不同类型的XML/Config配置文件,转化成不同的实体类型

  ②使用Lazy延迟读取,也就是只有在用到的时候才读,不用在Global里初始化

  ③使用Func方便处理特定的逻辑

  ④自动监控文件的更改变化

  ⑤使用非常方便

  FileWatcher的用法

  在看FileWatcher类源码之前,我们先来看一下基本的用法,首先我们先来准备一些基础数据,如下:

<?xml version="1.0" encoding="utf-8" ?>
<StateProvinceData xmlns="urn:com:company:project:v1">
  
<Country locale="ABW" hasStateProvinces="true" phonePrefix="297" />  <Country locale="ATG" hasStateProvinces="true" phonePrefix="1 268" />
  
<Country locale="USA" hasStateProvinces="true" phonePrefix="1" isPostalCodeRequired="true" >
    
<StateProvince value="Alabama">Alabama</StateProvince>
    
<StateProvince value="Alaska">Alaska</StateProvince>
    
<StateProvince value="Arizona">Arizona</StateProvince>
    
<StateProvince value="Texas">Texas</StateProvince>
    
<StateProvince value="Utah">Utah</StateProvince>
    
<StateProvince value="Vermont">Vermont</StateProvince>
    
<StateProvince value="Virginia">Virginia</StateProvince>
    
<StateProvince value="Washington">Washington</StateProvince>
    
<StateProvince value="West Virginia">West Virginia</StateProvince>
    
<StateProvince value="Wisconsin">Wisconsin</StateProvince>
    <StateProvince value="Wyoming">Wyoming</StateProvince>
  </Country>
  
<Country locale="UZB" hasStateProvinces="true" phonePrefix="998" />
  <Country locale="VAT" hasStateProvinces="true" phonePrefix="39" />
</StateProvinceData>

  主要是一个Country集合,每个Country下面有一些特殊的属性以及所拥有的省,这里我们只是节选一段例子。下面我们肯先来创建对于的实例类:

    [XmlRoot(Namespace="urn:com:company:project:v1")]
    
public class StateProvinceData
    {
        [XmlElement(
"Country")]
        
public Country[] Countries { get; set; }
    }
    [XmlType(Namespace
= "urn:com:company:project:v1")]
    
public class Country
    {
        [XmlAttribute(
"locale")]
        
public string Locale { get; set; }
        [XmlIgnore]
        
public string Name
        {
            
get { return (this.Locale != null) ? CountryName.ResourceManager.GetString(this.Locale) : ""; }
       
// 这一点比较特殊,主要是从资源文件读取内容,暂时忽略
        }
        [XmlAttribute(
"hasStateProvinces")]
        
public bool HasStateProvinces { get; set; }
        [XmlAttribute(
"isPostalCodeRequired")]
        
public bool IsPostalCodeRequired { get; set; }
        [XmlAttribute(
"phonePrefix")]        public string PhonePrefix { get; set; }
        [XmlElement(
"StateProvince")]
        
public StateProvince[] StateProvinces { get; set; }
    }
    [XmlType(Namespace
= "urn:com:company:project:v1")]
    
public class StateProvince
    {
        [XmlAttribute(
"value")]
        
public string Value;
        [XmlText]
        
public string Text;
    }

   这3个类主要是对应XML文件里的节点元素,通过XML的namespace和XMLAttribute来确保能和XML里的内容对应上。

  最后,我们来看一下基本用法:

public static class StateProvinceTable
{
    
// 通过Lazy达到延迟初始化的目的
    
// 其参数是一个CreateWatcher委托,用来加载数据
    
private static Lazy<FileWatcher<IDictionary<string, Country>>> dataWatcher =
        
new Lazy<FileWatcher<IDictionary<string, Country>>>(CreateWatcher);
    
//暴露数据给外部使用
    
public static IDictionary<string, Country> Data
    {
        
get { return dataWatcher.Value.Value; }
    }
    
private static FileWatcher<IDictionary<string, Country>> CreateWatcher()
    {
        
// 传入path和LoadData两个参数
        
// 其中LoadData参数是Func<FileStream, T>类型的委托,T目前就是IDictionary<string, Country>
        
return new FileWatcher<IDictionary<string, Country>>
            (HttpContext.Current.Server.MapPath(
"~/StateProvinceData.config"), LoadData);
    }
    
// 用来将FileStream转化成实体集合
    
private static IDictionary<string, Country> LoadData(FileStream configFile)
    {
        StateProvinceData dataTable
= (StateProvinceData)
            (
new XmlSerializer(typeof(StateProvinceData))).Deserialize(configFile);
        
return dataTable.Countries.ToDictionary(item => item.Locale);
    }
}

   这样,我们在任何地方通过引用StateProvinceTable.Data就可以使用了,不需要在Global里初始化加载,不需要自己担心XML数据被更改,直接用就OK了,所有的事情FileWatcher类已经帮你做了。

0
相关文章