Example #1
0
        /// <summary>
        /// 向 <see cref="IniConfig"/> 维护的 <see cref="IObject"/> 中设置一个对象并序列化成指定节名的 <see cref="ISection"/>, 若节名已存在将会覆盖整个节
        /// </summary>
        /// <param name="sectionKey">用作要添加的元素的键的对象</param>
        /// <param name="obj">用作要添加的元素的值的对象</param>
        /// <exception cref="ArgumentException">sectionKey 为空字符串或为 <see langword="null"/></exception>
        /// <exception cref="ArgumentNullException">obj 为 null</exception>
        public void SetObject(string sectionKey, object obj)
        {
            if (string.IsNullOrEmpty(sectionKey))
            {
                throw new ArgumentException("sectionKey 不允许为空. 原因: obj 不能设置到为未命名的节点", "sectoinKey");
            }
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            if (!this._object.ContainsKey(sectionKey))                // 如果不存在这个名称
            {
                this._object.Add(new ISection(sectionKey));
            }

            // 获取节对象
            ISection section = this._object[sectionKey];

            if (section.Count > 0)
            {
                section.Clear();
            }

            Type tType = obj.GetType();

            PropertyInfo[] tProperties = tType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (PropertyInfo property in tProperties)
            {
                // 获取属性是否有标记 KeyName
                IniKeyAttribute keyAttribute = property.GetCustomAttribute <IniKeyAttribute> ();

                string key = string.Empty;
                if (keyAttribute != null)
                {
                    key = keyAttribute.KeyName;
                }
                else
                {
                    key = property.Name;
                }

                // 判断 Key 重复
                if (section.ContainsKey(key))
                {
                    throw new ArgumentException("序列化的对象内部存在一个或多个重复的 Key, 这个异常可能由于属性名和特性引起.", "obj");
                }

                // 获取只有0个参数的 Get 方法 (排除索引器)
                MethodInfo method = property.GetGetMethod(true);
                if (method.GetParameters().Count() == 0)
                {
                    section.Add(key, new IValue(method.Invoke(obj, null)));
                }
            }
        }
Example #2
0
        /// <summary>
        /// 从 <see cref="IniConfig"/> 维护的 <see cref="IObject"/> 中获取一个指定节名的 <see cref="ISection"/> 反序列化成指定类型的对象
        /// </summary>
        /// <param name="sectionKey">用作要获取的元素的键的对象</param>
        /// <param name="t">用作要转换目标对象的类型的对象</param>
        /// <exception cref="ArgumentNullException">t 为 null</exception>
        /// <exception cref="ArgumentException">sectionKey 未能匹配到指定节点 或 t 不是 <see cref="RuntimeType"/>。 或 t 是开放式泛型类型(即,<see cref="Type.ContainsGenericParameters"/> 属性将返回 <see langword="true"/>)</exception>
        /// <exception cref="NotSupportedException">t 不能为 <see cref="TypeBuilder"/>。 或 不支持创建 <see cref="TypedReference"/>、<see cref="ArgIterator"/>、<see cref="Void"/>和 <see cref="RuntimeArgumentHandle"/> 类型,或者这些类型的数组。 或 包含 t 的程序集是一个用 <see cref="AssemblyBuilderAccess.Save"/> 创建的动态程序集</exception>
        /// <exception cref="TargetInvocationException">正在被调用的构造函数引发了一个异常</exception>
        /// <exception cref="MethodAccessException">调用方没有权限调用此构造函数</exception>
        /// <exception cref="MemberAccessException">无法创建抽象类的实例,或者此成员是使用晚期绑定机制调用的</exception>
        /// <exception cref="InvalidComObjectException">未通过 Overload:<see cref="Type.GetTypeFromProgID"/> 或 Overload:<see cref="Type.GetTypeFromCLSID"/> 获取 COM 类型</exception>
        /// <exception cref="COMException">t 是一个 COM 对象,但用于获取类型的类标识符无效,或标识的类未注册</exception>
        /// <exception cref="TypeLoadException">t 不是有效类型</exception>
        /// <exception cref="TargetException">尝试调用一个不存在的属性</exception>
        /// <returns>指定的对象实例</returns>
        public object GetObject(string sectionKey, Type t)
        {
            if (t == null)
            {
                throw new ArgumentNullException("t");
            }
            if (!this._object.ContainsKey(sectionKey))                // 如果不存在这个名称
            {
                throw new ArgumentException("未能找到与传入节名匹配的节点, 请检查节名是否有效", "sectionKey");
            }

            // 实例化对象
            object instance = Activator.CreateInstance(t, true);

            // 获取属性列表
            List <PropertyInfo> properties = new List <PropertyInfo> (t.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance));

            // 获取节点
            ISection section = this._object[sectionKey];

            foreach (KeyValuePair <string, IValue> item in section)
            {
                if (properties.Count == 0)
                {
                    throw new TargetException(string.Format("正在尝试调用一个不存在的属性 {0} 引发异常", item.Key));
                }

                for (int i = 0; i < properties.Count; i++)
                {
                    IniKeyAttribute keyAttribute = properties[i].GetCustomAttribute <IniKeyAttribute> ();
                    if ((keyAttribute != null && keyAttribute.KeyName.Equals(item.Key)) || properties[i].Name.Equals(item.Key))
                    {
                        MethodInfo method = properties[i].GetSetMethod(true);
                        if (method.GetParameters().Count() == 0)
                        {
                            method.Invoke(instance, new object[] { item.Value });
                        }

                        properties.RemoveAt(i);
                        break;
                    }
                }
            }

            return(instance);
        }