Exemplo n.º 1
0
        /// <exception cref="ArgumentException">
        ///   The given type implements the <see cref="IXmlCustomSerialized" /> interface but does not define a constructor accepting
        ///   <see cref="XmlDeserializationProvider" /> as parameter.
        /// </exception>
        private void ReflectTypeData(IEnumerable <Type> typesToCache = null)
        {
            if (this.TargetType == null)
            {
                throw new InvalidOperationException();
            }

            this.isCustomSerialized = (this.TargetType.GetInterface("IXmlCustomSerialized", false) != null);

            if (this.IsCustomSerialized)
            {
                if (this.TargetType.GetConstructor(new[] { typeof(XmlDeserializationProvider) }) == null)
                {
                    var ex = new XmlSerializationException("The type implements the IXmlCustomSerialized interface but does not define a constructor accepting XmlDeserializationProvider as parameter.");
                    ex.Data.Add("Type Name", this.TargetType.FullName);
                    throw ex;
                }
            }
            else if (!this.TargetType.IsValueType) // A value type will always provide a parameterless constructor.
            {
                if (this.Settings.AllowsDeserialization && this.TargetType.GetConstructor(new Type[] {}) == null)
                {
                    var ex = new XmlSerializationException("The type has to implement a parameterless constructor to be deserialized.");
                    ex.Data.Add("Type Name", this.TargetType.FullName);
                    throw ex;
                }
            }

            // The types where reflection data has to be cached (where sub serializers have to be created) for.
            List <Type> typesToCacheNew = new List <Type>(20);

            if (typesToCache != null)
            {
                foreach (Type typeToCache in typesToCache)
                {
                    typesToCacheNew.Add(typeToCache);
                }
            }

            // Reflect Members
            MemberInfo[] memberInfos = this.TargetType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
            this.serializableMembers = new XmlSerializableMemberCollection();

            foreach (MemberInfo memberInfo in memberInfos)
            {
                XmlSerializableMember member = XmlSerializableMember.Create(memberInfo, typesToCacheNew, this.Settings);

                if (member != null)
                {
                    this.serializableMembers.Add(member);
                }
            }
            // Sort the members by their OrderIndex value.
            this.serializableMembers.Sort();

            for (Int32 i = 0; i < typesToCacheNew.Count; i++)
            {
                Type typeToCache = typesToCacheNew[i];

                if (
                    typeToCache != this.TargetType && typeToCache != null && !this.subSerializers.ContainsKey(typeToCache) &&
                    !XmlSerializationProvider.IsNativelySerializable(typeToCache)
                    )
                {
                    try {
                        this.subSerializers.Add(typeToCache, new XmlSerializer <Object>(typeToCache, this.subSerializers, this.Settings));
                    } catch (Exception exception) {
                        var ex = new XmlSerializationException(
                            "The type is not serializable. See inner exception for more details.", exception);
                        ex.Data.Add("Type", typeToCache);
                        throw ex;
                    }
                }
            }
        }