예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObjectDescriptor" /> class.
        /// </summary>
        public ObjectDescriptor(ITypeDescriptorFactory factory, Type type, bool emitDefaultValues, IMemberNamingConvention namingConvention)
        {
            if (factory == null)
            {
                throw new ArgumentNullException(nameof(factory));
            }
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }
            if (namingConvention == null)
            {
                throw new ArgumentNullException(nameof(namingConvention));
            }

            this.factory           = factory;
            Type                   = type;
            IsCompilerGenerated    = AttributeRegistry.GetAttribute <CompilerGeneratedAttribute>(type) != null;
            this.emitDefaultValues = emitDefaultValues;
            NamingConvention       = namingConvention;

            Attributes = AttributeRegistry.GetAttributes(type);

            Style = DataStyle.Any;
            foreach (var attribute in Attributes)
            {
                var styleAttribute = attribute as DataStyleAttribute;
                if (styleAttribute != null)
                {
                    Style = styleAttribute.Style;
                }
            }

            // Get DefaultMemberMode from DataContract
            DefaultMemberMode = DataMemberMode.Default;
            var currentType = type;

            while (currentType != null)
            {
                var dataContractAttribute = AttributeRegistry.GetAttribute <DataContractAttribute>(currentType);
                if (dataContractAttribute != null && (dataContractAttribute.Inherited || currentType == type))
                {
                    DefaultMemberMode = dataContractAttribute.DefaultMemberMode;
                    break;
                }
                currentType = currentType.BaseType;
            }
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObjectDescriptor" /> class.
        /// </summary>
        /// <param name="factory">The factory.</param>
        /// <param name="type">The type.</param>
        /// <exception cref="System.ArgumentNullException">type</exception>
        /// <exception cref="System.InvalidOperationException">Failed to get ObjectDescriptor for type [{0}]. The member [{1}] cannot be registered as a member with the same name is already registered [{2}].ToFormat(type.FullName, member, existingMember)</exception>
        public ObjectDescriptor(ITypeDescriptorFactory factory, Type type)
        {
            if (factory == null)
            {
                throw new ArgumentNullException("factory");
            }
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            this.factory           = factory;
            Category               = DescriptorCategory.Object;
            this.AttributeRegistry = factory.AttributeRegistry;
            this.type              = type;
            var styleAttribute = AttributeRegistry.GetAttribute <DataStyleAttribute>(type);

            this.style = styleAttribute != null ? styleAttribute.Style : DataStyle.Any;
            this.IsCompilerGenerated = AttributeRegistry.GetAttribute <CompilerGeneratedAttribute>(type) != null;
        }
예제 #3
0
        protected bool IsMemberToVisit(MemberInfo memberInfo)
        {
            // Remove all SyncRoot from members
            if (memberInfo is PropertyInfo && memberInfo.Name == "SyncRoot" && memberInfo.DeclaringType != null && (memberInfo.DeclaringType.Namespace ?? string.Empty).StartsWith(SystemCollectionsNamespace))
            {
                return(false);
            }

            Type memberType = null;
            var  fieldInfo  = memberInfo as FieldInfo;

            if (fieldInfo != null)
            {
                memberType = fieldInfo.FieldType;
            }
            else
            {
                var propertyInfo = memberInfo as PropertyInfo;
                if (propertyInfo != null)
                {
                    memberType = propertyInfo.PropertyType;
                }
            }

            if (memberType != null)
            {
                if (typeof(Delegate).IsAssignableFrom(memberType))
                {
                    return(false);
                }
            }


            // Member is not displayed if there is a YamlIgnore attribute on it
            if (AttributeRegistry.GetAttribute <DataMemberIgnoreAttribute>(memberInfo) != null)
            {
                return(false);
            }

            return(true);
        }
예제 #4
0
        protected virtual bool PrepareMember(MemberDescriptorBase member)
        {
            var memberType = member.Type;

            // Start with DataContractAttribute.DefaultMemberMode (if set)
            member.Mode = DefaultMemberMode;
            member.Mask = 1;


            // Gets the style
            var styleAttribute = AttributeRegistry.GetAttribute <DataStyleAttribute>(member.MemberInfo);

            if (styleAttribute != null)
            {
                member.Style       = styleAttribute.Style;
                member.ScalarStyle = styleAttribute.ScalarStyle;
            }

            // Handle member attribute
            var memberAttribute = AttributeRegistry.GetAttribute <DataMemberAttribute>(member.MemberInfo);

            if (memberAttribute != null)
            {
                ((IMemberDescriptor)member).Mask = memberAttribute.Mask;
                if (!member.HasSet)
                {
                    if (memberAttribute.Mode == DataMemberMode.Assign ||
                        (memberType.IsValueType && member.Mode == DataMemberMode.Content))
                    {
                        throw new ArgumentException($"{memberType.FullName} {member.OriginalName} is not writeable by {memberAttribute.Mode.ToString()}.");
                    }
                }

                member.Mode  = memberAttribute.Mode;
                member.Order = memberAttribute.Order;
            }

            // If mode is Default, let's resolve to the actual mode depending on getter/setter existence and object type
            if (member.Mode == DataMemberMode.Default)
            {
                // The default mode is Content, which will not use the setter to restore value if the object is a class (but behave like Assign for value types)
                member.Mode = DataMemberMode.Content;
                if (!member.HasSet && (memberType == typeof(string) || !memberType.IsClass) && !memberType.IsInterface && !Type.IsAnonymous())
                {
                    // If there is no setter, and the value is a string or a value type, we won't write the object at all.
                    member.Mode = DataMemberMode.Never;
                }
            }

            // Process all attributes just once instead of getting them one by one
            var attributes = AttributeRegistry.GetAttributes(member.MemberInfo);
            DefaultValueAttribute defaultValueAttribute = null;

            foreach (var attribute in attributes)
            {
                var valueAttribute = attribute as DefaultValueAttribute;
                if (valueAttribute != null)
                {
                    defaultValueAttribute = valueAttribute;
                    continue;
                }

                var yamlRemap = attribute as DataAliasAttribute;
                if (yamlRemap != null)
                {
                    if (member.AlternativeNames == null)
                    {
                        member.AlternativeNames = new List <string>();
                    }
                    if (!string.IsNullOrWhiteSpace(yamlRemap.Name))
                    {
                        member.AlternativeNames.Add(yamlRemap.Name);
                    }
                }
            }


            // If it's a private member, check it has a YamlMemberAttribute on it
            if (!member.IsPublic)
            {
                if (memberAttribute == null)
                {
                    return(false);
                }
            }

            if (member.Mode == DataMemberMode.Binary)
            {
                if (!memberType.IsArray)
                {
                    throw new InvalidOperationException($"{memberType.FullName} {member.OriginalName} of {Type.FullName} is not an array. Can not be serialized as binary.");
                }
                if (!memberType.GetElementType().IsPureValueType())
                {
                    throw new InvalidOperationException($"{memberType.GetElementType()} is not a pure ValueType. {memberType.FullName} {member.OriginalName} of {Type.FullName} can not serialize as binary.");
                }
            }

            // If this member cannot be serialized, remove it from the list
            if (member.Mode == DataMemberMode.Never)
            {
                return(false);
            }

            // ShouldSerialize
            //	  YamlSerializeAttribute(Never) => false
            //	  ShouldSerializeSomeProperty => call it
            //	  DefaultValueAttribute(default) => compare to it
            //	  otherwise => true
            var shouldSerialize = Type.GetMethod("ShouldSerialize" + member.OriginalName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

            if (shouldSerialize != null && shouldSerialize.ReturnType == typeof(bool) && member.ShouldSerialize == null)
            {
                member.ShouldSerialize = obj => (bool)shouldSerialize.Invoke(obj, EmptyObjectArray);
            }

            if (defaultValueAttribute != null && member.ShouldSerialize == null && !emitDefaultValues)
            {
                object defaultValue = defaultValueAttribute.Value;
                Type   defaultType  = defaultValue?.GetType();
                if (defaultType.IsNumeric() && defaultType != memberType)
                {
                    defaultValue = memberType.CastToNumericType(defaultValue);
                }
                member.ShouldSerialize = obj => !Equals(defaultValue, member.Get(obj));
            }

            if (member.ShouldSerialize == null)
            {
                member.ShouldSerialize = ShouldSerializeDefault;
            }

            member.Name = !string.IsNullOrEmpty(memberAttribute?.Name) ? memberAttribute.Name : NamingConvention.Convert(member.OriginalName);

            return(true);
        }
예제 #5
0
        protected virtual bool PrepareMember(MemberDescriptorBase member)
        {
            var memberType = member.Type;

            // If the member has a set, this is a conventional assign method
            if (member.HasSet)
            {
                member.Mode = DataMemberMode.Assign;
            }
            else
            {
                // Else we cannot only assign its content if it is a class
                member.Mode = (memberType != typeof(string) && memberType.IsClass) || memberType.IsInterface || type.IsAnonymous() ? DataMemberMode.Content : DataMemberMode.Never;
            }

            // Gets the style
            var styleAttribute = AttributeRegistry.GetAttribute <DataStyleAttribute>(member.MemberInfo);

            member.Style = styleAttribute != null ? styleAttribute.Style : DataStyle.Any;

            // Handle member attribute
            var memberAttribute = AttributeRegistry.GetAttribute <DataMemberAttribute>(member.MemberInfo);

            if (memberAttribute != null)
            {
                if (!member.HasSet)
                {
                    if (memberAttribute.Mode == DataMemberMode.Assign ||
                        (memberType.IsValueType && member.Mode == DataMemberMode.Content))
                    {
                        throw new ArgumentException("{0} {1} is not writeable by {2}.".ToFormat(memberType.FullName, member.Name, memberAttribute.Mode.ToString()));
                    }
                }

                if (memberAttribute.Mode != DataMemberMode.Default)
                {
                    member.Mode = memberAttribute.Mode;
                }
                member.Order = memberAttribute.Order;
            }

            if (member.Mode == DataMemberMode.Binary)
            {
                if (!memberType.IsArray)
                {
                    throw new InvalidOperationException("{0} {1} of {2} is not an array. Can not be serialized as binary."
                                                        .ToFormat(memberType.FullName, member.Name, type.FullName));
                }
                if (!memberType.GetElementType().IsPureValueType())
                {
                    throw new InvalidOperationException("{0} is not a pure ValueType. {1} {2} of {3} can not serialize as binary.".ToFormat(memberType.GetElementType(), memberType.FullName, member.Name, type.FullName));
                }
            }

            // If this member cannot be serialized, remove it from the list
            if (member.Mode == DataMemberMode.Never)
            {
                return(false);
            }

            if (memberAttribute != null && !string.IsNullOrEmpty(memberAttribute.Name))
            {
                member.Name = memberAttribute.Name;
            }

            return(true);
        }