设为首页 加入收藏

TOP

动态类型序列化(一)
2019-09-17 18:55:11 】 浏览:106
Tags:动态 类型 序列化

上一篇文章直接就被移除首页了,这次来点大家都能懂的干货.

需求

之前做一个winform的工具时候有以下几个需求
1. 主窗体(或者叫平台)可以安装若干类型的插件。
2. 插件关闭时候需要保存状态。
3. 插件加载的时候可以加载上次关闭的配置。
4. 插件中的配置可以切换。
5. 主窗体本身保存当前插件,并且可以通过不同的配置文件切换插件

使用上最方便的做法是将配置给平台来管理。但是平台本身并不知道插件要保存怎样的配置。针对以上问题在配置这个上做了如下设计

设计

1. 动态类型序列化以满足插件的任何配置需要
2. 动态类型基本的就是dynamic,那么我们需用字典作为实现
3. 支持具体的类进行序列化,那么此时需要用xml保存类的元数据信息
4. 支持接口的序列化,此时也是保存实际类型的元数据信息
5. 支持List序列化
6. 支持Arry序列化
7. 支持Dictionary序列化

接口定义


其中PathOrSourceString 属性这样既可以支持文件,也可以直接支持字符串,扩展更加方便.

public interface IConfig
    {
        string PathOrSourceString { get; set; }

        dynamic Data { get; set; }
    }

 

动态类型实现


这里是基于字典,网上有很多类似的代码。

这里字典的Value设计成dynamic是为了嵌套。

    [Serializable]
    public class DynamicDictionary : DynamicObject
    {
        private Dictionary<string, dynamic> _dictionary = new Dictionary<string, dynamic>();

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            string name = binder.Name;
            if (!_dictionary.ContainsKey(name))
            {
                _dictionary.Add(name, new DynamicDictionary());
            }
            return _dictionary.TryGetValue(name, out result);
        }

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            var key = binder.Name;
            if (_dictionary.ContainsKey(key))
                _dictionary[key] = value;
            else
            {
                _dictionary.Add(key, value);
            }


            return true;
        }

        public Dictionary<string, dynamic> Dictionary
        {
            get { return _dictionary; }
        }

        public void AddMember(string name, dynamic value)
        {
            _dictionary.Add(name, value);
        }
    }

  

配置的加载和保存逻辑(核心)

 

    public static class ConfigManager
    {
        public static IConfig LoadFromFile(this IConfig config)
        {
            if (config == null || string.IsNullOrEmpty(config.PathOrSourceString))
                throw new ArgumentNullException("config");
            if (!File.Exists(config.PathOrSourceString))
            {
                return config;
            }
            var doc = new XmlDocument();
            doc.Load(config.PathOrSourceString);
            var element = doc["Data"];
            config.Data = GetValue(element);
            return config;
        }

        public static IConfig SaveToFile(this IConfig config)
        {
            if (config == null || string.IsNullOrEmpty(config.PathOrSourceString) || config.Data == null)
                throw new ArgumentNullException("config");
            var dir = Path.GetDirectoryName(config.PathOrSourceString);
            if (!Directory.Exists(dir))
                Directory.CreateDirectory(dir);
            var doc = new XmlDocument();
            doc.AppendChild(GetXml("Data", config.Data, doc));
            doc.Save(config.PathOrSourceString);
            return config;
        }

        public static IConfig LoadFromString(this IConfig config)
        {
            if (config == null || string.IsNullOrEmpty(config.PathOrSourceString))
                throw new ArgumentNullException("config");
            var doc = new XmlDocument();
            doc.LoadXml(config.PathOrSourceString);
            var element = doc["Data"];
            config.Data = GetValue(element);
            return config;
        }

        public static IConfig SaveToString(this IConfig config)
        {
            if (config == null || config.Data == null)
                throw new ArgumentNullException("config");
            var doc = new XmlDocument();
            doc.AppendChild(GetXml("Data", config.Data, doc));
            config.PathOrSourceString = doc.OuterXml;
            return config;
        }

        #region 解析XmlElement

        public static dynamic GetValue(XmlElement element)
        {
            if (element == null)
                return null;
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/7/7
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇理解依赖注入和控制反转 下一篇RefulApi自动化测试~Hitchhiker的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目