首页 > 代码库 > 【WP8】自定义配置存储类

【WP8】自定义配置存储类

之前在WP7升级到WP8的时候遇到配置不兼容的问题

情景:之前只有一个WP7版本,现在需要发布WP8版本,让用户可以从原来的WP7版本升级到WP8版本

  一般情况下从WP7升级到WP8没什么问题

  但是在项目中升级到WP8的时候,原先在WP7下保存在IsolatedStorageSettings的数据都不出来,经过调试发现

1、IsolatedStorageSettings存放数据的隔离存储控件的"__ApplicationSettings"文件中,存放的格式如下 {"test":"TestData"}

<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">    <KeyValueOfstringanyType>        <Key>test</Key>        <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">TestData</Value>    </KeyValueOfstringanyType></ArrayOfKeyValueOfstringanyType>

 

2、但是原来的项目中使用了友盟WP7版本,后来的项目中使用的是WP8版本,友盟会向"__ApplicationSettings"文件中写入数据,如下:

UmengSDK.Business.OnlineConfigManager+OnlineConfig, UmengAnalyticsWP7, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null<ArrayOfKeyValueOfstringanyType xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">    <KeyValueOfstringanyType>        <Key>test</Key>        <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">TestData</Value>    </KeyValueOfstringanyType>    <KeyValueOfstringanyType>        <Key>device_id</Key>        <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">0BBB2DF41DD5688A25517F2968339DC0</Value>    </KeyValueOfstringanyType>    <KeyValueOfstringanyType>        <Key>wp_device</Key>        <Value xmlns:d3p1="http://www.w3.org/2001/XMLSchema" i:type="d3p1:string">1C43AC07795C55C2ADA78B0DD5A79B3660A7D137</Value>    </KeyValueOfstringanyType>    <KeyValueOfstringanyType>        <Key>config</Key>        <Value xmlns:d3p1="http://schemas.datacontract.org/2004/07/UmengSDK.Business" i:type="d3p1:OnlineConfigManager.OnlineConfig">            <d3p1:Interval>30</d3p1:Interval>            <d3p1:LastConfigTime>Wed Jul 02 00:43:35 CST 2014</d3p1:LastConfigTime>            <d3p1:Policy>BATCH_AT_LAUNCH</d3p1:Policy>        </Value>    </KeyValueOfstringanyType></ArrayOfKeyValueOfstringanyType>

 

3、而上面数据到了WP8上就不能正常读取原来存放的数据(如果在WP8项目中用WP7版的友盟则可以正常读取),导致原来存放的其他信息也读取不出来

4、下面试图自定义一个与 IsolatedStorageSettings 功能类似的类用于小数据的存取,避免第三方类库对"__ApplicationSettings"文件的修改导致一些兼容性问题

  IsolatedStorageSettings 存放的是键值对,也就是字典模型,我们需要把Dictionary序列化到文件中,但是Dictionary不支持直接序列化,先对Dictionary进行扩展,让其支持序列化

using System;using System.Collections.Generic;using System.Xml;using System.Xml.Schema;using System.Xml.Serialization;namespace XTuOne.Common.Helpers{    /// <summary>    /// 可序列化的Dictionary    /// </summary>    [XmlRoot("Dictionary")]    public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable    {        #region 构造函数,调用基类的构造函数        public SerializableDictionary()        {        }        public SerializableDictionary(IDictionary<TKey, TValue> dictionary)            : base(dictionary)        {        }        public SerializableDictionary(IEqualityComparer<TKey> comparer)            : base(comparer)        {        }        public SerializableDictionary(int capacity)            : base(capacity)        {        }        public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)            : base(capacity, comparer)        {        }        public SerializableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)            : base(dictionary, comparer)        {        }        #endregion        #region IXmlSerializable 接口的实现        public XmlSchema GetSchema()        {            throw new NotImplementedException();        }        /// <summary>        /// 从对象的XML表示形式生成该对象        /// </summary>        /// <param name="reader"></param>        public void ReadXml(XmlReader reader)        {            var keySerializer = new XmlSerializer(typeof (TKey));            var valueSerializer = new XmlSerializer(typeof (TValue));            bool wasEmpty = reader.IsEmptyElement;            reader.Read();            if (wasEmpty)                return;            while (reader.NodeType != XmlNodeType.EndElement)            {                reader.ReadStartElement("Key");                TKey key = (TKey) keySerializer.Deserialize(reader);                reader.ReadEndElement();                reader.ReadStartElement("Value");                TValue value = (TValue) valueSerializer.Deserialize(reader);                reader.ReadEndElement();                this.Add(key, value);                reader.MoveToContent();            }            reader.ReadEndElement();        }        /// <summary>        /// 将对象转换为其XML表示形式        /// </summary>        /// <param name="writer"></param>        public void WriteXml(XmlWriter writer)        {            var keySerializer = new XmlSerializer(typeof (TKey));            var valueSerializer = new XmlSerializer(typeof (TValue));            foreach (TKey key in this.Keys)            {                writer.WriteStartElement("Key");                keySerializer.Serialize(writer, key);                writer.WriteEndElement();                writer.WriteStartElement("Value");                TValue value = this[key];                valueSerializer.Serialize(writer, value);                writer.WriteEndElement();            }        }        #endregion    }}
View Code

5、使用系统的Xml序列化功能保存数据

using System;using System.IO;using System.IO.IsolatedStorage;using System.Windows;using System.Xml.Linq;using System.Xml.Serialization;namespace XTuOne.Common.Helpers{    public class XmlHelper    {        private XmlHelper()        {        }        /// <summary>        /// 序列化对象到文件        /// </summary>        /// <param name="file">文件路径:"/test.xml"</param>        /// <param name="obj"></param>        public static void Serialize<T>(string file, T obj)        {            using (var sf = IsolatedStorageFile.GetUserStoreForApplication())            {                using (var fs = new IsolatedStorageFileStream(file, FileMode.OpenOrCreate, FileAccess.Write, sf))                {                    var serializer = new XmlSerializer(obj.GetType());                    serializer.Serialize(fs, obj);                }            }        }        /// <summary>        /// 反序列化文件到对象        /// </summary>        /// <typeparam name="T"></typeparam>        /// <param name="file">文件路径:"/test.xml"</param>        public static T Deserialize<T>(string file)        {            using (var sf = IsolatedStorageFile.GetUserStoreForApplication())            {                var serializer = new XmlSerializer(typeof(T));                using (var fs = sf.OpenFile(file, FileMode.Open, FileAccess.Read))                {                    return (T)serializer.Deserialize(fs);                }            }        }        /// <summary>        /// 读取配置文件的信息        /// </summary>        /// <param name="file">前面不加/</param>        /// <param name="node">用.隔开(例如App.Version)</param>        /// <param name="attribute"></param>        public static string GetConfigValue(string file,string node, string attribute)        {            var configFile = Application.GetResourceStream(new Uri(file, UriKind.Relative));            return GetXmlValue(configFile.Stream, node, attribute);        }        private static string GetXmlValue(Stream stream, string node, string attribute)        {            var configDoc = XDocument.Load(stream);            XElement temp = null;            foreach (var n in node.Split(.))            {                if (temp == null)                {                    temp = configDoc.Element(n);                    continue;                }                temp = temp.Element(n);            }            if (temp == null)            {                throw new NullReferenceException();            }            return temp.Attribute(attribute).Value;        }    }}
XmlHelper
// *************************************************// // 作者:bomo// 小组:WP开发组// 创建日期:2014/6/21 14:55:56// 版本号:V1.00// 说明:// // *************************************************// // 修改历史: // Date                WhoChanges        Made // 2014/6/21 14:55:56            bomo         Initial creation //// *************************************************using System.IO.IsolatedStorage;namespace XTuOne.Common.Helpers{    /// <summary>    /// 自定义应用程序配置(相当于IsolatedStorageSetting)    /// </summary>    public class ApplicationSetting    {        /// <summary>        /// 保存配置的文件名        /// </summary>        private const string SETTING_FILE = "XTuOneSetting";        private static SerializableDictionary<string, object> dictionary;        #region 单例        private static ApplicationSetting current;        private static readonly object lockObj = new object();        private ApplicationSetting()        {            //读取配置            using (var sf = IsolatedStorageFile.GetUserStoreForApplication())            {                dictionary = sf.FileExists(SETTING_FILE) ? XmlHelper.Deserialize<SerializableDictionary<string, object>>(SETTING_FILE) : new SerializableDictionary<string, object>();            }        }        public static ApplicationSetting Current        {            get            {                if (current == null)                {                    lock (lockObj)                    {                        if (current == null)                        {                            current = new ApplicationSetting();                        }                    }                }                return current;            }        }        #endregion        /// <summary>        /// 通过索引赋值需要显式保存        /// </summary>        public object this[string key]        {            get { return Contains(key) ? dictionary[key] : null; }            set { dictionary[key] = value.ToString(); }        }        public T Get<T>(string key)        {            return (T) dictionary[key];        }        /// <summary>        /// 通过键获取值,如果不存在,则返回传入的默认值        /// </summary>        public T Get<T>(string key, T defaultValue)        {            return dictionary.ContainsKey(key) ? (T) dictionary[key] : defaultValue;        }        /// <summary>        /// 设置值,自动保存        /// </summary>        public void Set(string key, object value)        {            if (dictionary.ContainsKey(key))            {                dictionary[key] = value;            }            else            {                dictionary.Add(key, value);            }            Save();        }        /// <summary>        /// 保存配置到文件        /// </summary>        public void Save()        {            XmlHelper.Serialize(SETTING_FILE, dictionary);        }        /// <summary>        /// 判断是否包含键        /// </summary>        public bool Contains(string key)        {            return dictionary.ContainsKey(key);        }        /// <summary>        /// 析构时保存数据        /// </summary>        ~ApplicationSetting()        {            Save();        }    }}

 

使用自定义的配置管理器可以控制文件信息,不会出现上述与第三方类库的一些兼容性问题(当然,这种情况比较少)