【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进行扩展,让其支持序列化

【WP8】自定义配置存储类
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序列化功能保存数据

【WP8】自定义配置存储类
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;

using System.IO.IsolatedStorage;

using XTuOne.Common.Helpers;



namespace XTuOne.Utility.Helpers

{

    /// <summary>

    /// 自定义应用程序配置(相当于IsolatedStorageSetting)

    /// </summary>

    public class ApplicationSetting

    {

        /// <summary>

        /// 保存配置的文件名

        /// </summary>

        private readonly string filePath;



        private readonly SerializableDictionary<string, object> dictionary;



        public ApplicationSetting(string filePath)

        {

            this.filePath = filePath;

            //读取配置

            using (var sf = IsolatedStorageFile.GetUserStoreForApplication())

            {

                var directory = Path.GetDirectoryName(filePath);

                if (directory != null)

                {

                    if (sf.DirectoryExists(directory))

                    {

                        sf.CreateDirectory(directory);

                    }

                }



                dictionary = sf.FileExists(filePath)

                    ? XmlHelper.Deserialize<SerializableDictionary<string, object>>(filePath)

                    : new SerializableDictionary<string, object>();

            }

        }



        /// <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(filePath, dictionary);

        }



        /// <summary>

        /// 判断是否包含键

        /// </summary>

        public bool Contains(string key)

        {

            return dictionary.ContainsKey(key);

        }



        /// <summary>

        /// 析构时保存数据

        /// </summary>

        ~ApplicationSetting()

        {

            Save();

        }

    }

}

 

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

注意:该配置文件只支持基础类型,不支持复杂类型

你可能感兴趣的:(自定义)