[fix]Config创建默认配置文件的开关Runtime.CreateConfigOnMissing,仅需对自动创建生效,而不应该阻止用户主动Save
智能大石头 authored at 2024-08-09 00:30:41 石头 committed at 2024-08-10 14:22:24
3.41 KiB
X
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using NewLife.Serialization;

namespace NewLife.Messaging
{
    /// <summary>指定类型的实体对象数组消息</summary>
    /// <remarks>
    /// 有些列表对象不适合直接序列化,并且不方便每次都进行转换,(如XCode的EntityList),此时适合用实体数组消息。
    /// 实体对象个数由<see cref="Values"/>决定,以编码整数来存储。
    /// 不写长度,所以<see cref="Message"/>为空时后面不能有其它包
    /// </remarks>
    public class EntitiesMessage : Message, IAccessor
    {
        /// <summary>消息类型</summary>
        [XmlIgnore]
        public override MessageKind Kind { get { return MessageKind.Entities; } }

        private Type _Type;
        /// <summary>实体类型。可以是接口或抽象类型(要求对象容器能识别)</summary>
        public Type Type
        {
            get
            {
                if (_Type == null && _Values != null && _Values.Count > 0) _Type = _Values[0].GetType();
                return _Type;
            }
            set { _Type = value; }
        }

        private IList _Values;
        /// <summary>实体列表</summary>
        public IList Values
        {
            get { return _Values ?? (_Values = new List<Object>()); }
            set
            {
                _Values = value;
                if (value != null && value.Count > 0)
                {
                    foreach (var item in value)
                    {
                        if (item != null)
                        {
                            _Type = item.GetType();
                            break;
                        }
                    }
                }
            }
        }

        #region IAccessor 成员
        Boolean IAccessor.Read(IReader reader)
        {
            reader.Depth++;

            Object v = null;
            if (!reader.ReadObject(typeof(Type), ref v, null)) return false;
            Type = v as Type;
            if (Type != null)
            {
                var lt = typeof(List<>).MakeGenericType(Type);

                v = null;
                if (!reader.ReadObject(lt, ref v, null)) return false;
                Values = v as IList;
            }
            reader.Depth--;
            return true;
        }

        Boolean IAccessor.ReadComplete(IReader reader, Boolean success) { return success; }

        Boolean IAccessor.Write(IWriter writer)
        {
            writer.Depth++;
            writer.WriteObject(Type);
            if (Type != null)
            {
                var lt = typeof(List<>).MakeGenericType(Type);
                writer.WriteObject(Values, lt, null);
            }
            writer.Depth--;
            return true;
        }

        Boolean IAccessor.WriteComplete(IWriter writer, Boolean success) { return success; }
        #endregion

        #region 辅助
        /// <summary>已重载。</summary>
        /// <returns></returns>
        public override string ToString()
        {
            var vs = Values;
            if (vs != null)
                return String.Format("{0} Type={1} Count={2}", base.ToString(), Type, vs.Count);
            else
                return base.ToString();
        }
        #endregion
    }
}