public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            var instance         = MethodFactory.CreateInstance(destinationType);
            var classDescription = serializationContext.GetClassDescription(destinationType, instance);
            var source           = value as IDictionary <string, object>;

            if (source != null)
            {
                foreach (var kv in source)
                {
                    IMemberWrapper wrapper;
                    if (classDescription.TryGetMember(kv.Key, out wrapper))
                    {
                        wrapper.SetValue(instance, kv.Value);
                    }
                }
                return(instance);
            }
            return(base.ConvertTo(context, culture, value, destinationType));
        }
Пример #2
0
        // Add the type to the list of creatable types
        public void Register(Type type)
        {
            if (type.IsEnum || constructors.ContainsKey(type))
            {
                return;
            }

            var constructor = type.GetConstructors().FirstOrDefault(x => x.GetParameters().Length == 0);

            if (constructor == null)
            {
                throw new ArgumentException($"{type.FullName} does not have any accessible parameterless constructors.", nameof(type));
            }

            constructors[type] = MethodFactory.CompileObjectConstructor(constructor);

            var attributes = type.GetCustomAttributes <SerializedNameAttribute>(false).ToArray();

            if (attributes.Length == 0)
            {
                remoteToLocalNames[type.FullName] = type;
            }
            else if (attributes.Count(x => x.Canonical) == 1)
            {
                foreach (var attribute in attributes)
                {
                    RegisterAlias(type, attribute.SerializedName, attribute.Canonical);
                }
            }
            else
            {
                throw new ArgumentException(
                          $"{type.FullName} has {attributes.Count(x => x.Canonical)} candidate names marked as canonical. only one can be canonical.",
                          nameof(type));
            }
        }
Пример #3
0
        public static object ConvertTo(object value, Type targetType)
        {
            if (value == null)
            {
                return(CreateDefaultValue(targetType));
            }

            var sourceType = value.GetType();

            if (sourceType == targetType || targetType.IsInstanceOfType(value))
            {
                return(value);
            }

            // IConvertible
            if (sourceType.IsConvertible() && targetType.IsConvertible())
            {
                if (targetType.IsEnum)
                {
                    var stringValue = value as string;
                    return(stringValue != null
                        ? Enum.Parse(targetType, stringValue, true)
                        : Enum.ToObject(targetType, value));
                }

                return(ConvertObject(sourceType, targetType, value));
            }

            var ienumerable = value as IEnumerable;

            // array
            if (targetType.IsArray && ienumerable != null)
            {
                var sourceElementType      = sourceType.GetElementType();
                var destinationElementType = targetType.GetElementType();

                var enumerable = ienumerable.Cast <object>();

                if (!destinationElementType.IsAssignableFrom(sourceElementType))
                {
                    enumerable = enumerable.Select(x => ConvertTo(x, destinationElementType));
                }

                var method = EnumerableToArrayCache.GetOrAdd(destinationElementType, type => EnumerableToArrayMethod.MakeGenericMethod(type));
                return(method.Invoke(null, new object[] { enumerable }));
            }

            // IDictionary<K, V>
            //     - we always deserialize AMF dictionaries as Dictionary<string, object> (or an object that inherits from it)
            var sourceGenericDictionary = value as IDictionary <string, object>;
            var genericDictionaryType   = TryGetInterfaceType(targetType, typeof(IDictionary <,>));

            if (sourceGenericDictionary != null && genericDictionaryType != null)
            {
                var instance = MethodFactory.CreateInstance(targetType);
                var adder    = AdderMethodCache.GetOrAdd(genericDictionaryType, type => new AdderMethodInfo(type));

                foreach (var pair in sourceGenericDictionary)
                {
                    adder.Method.Invoke(instance, new[]
                    {
                        ConvertTo(pair.Key, adder.TypeGenericParameters[0]),
                        ConvertTo(pair.Value, adder.TypeGenericParameters[1])
                    });
                }

                return(instance);
            }

            // IDictionary
            var souceDictionary = value as IDictionary;

            if (typeof(IDictionary).IsAssignableFrom(targetType) && souceDictionary != null)
            {
                var instance = (IDictionary)MethodFactory.CreateInstance(targetType);
                foreach (DictionaryEntry pair in souceDictionary)
                {
                    instance.Add(pair.Key, pair.Value);
                }
                return(instance);
            }

            // IList<T>
            var sourceListType = TryGetInterfaceType(targetType, typeof(IList <>));

            if (sourceListType != null && ienumerable != null)
            {
                var instance = MethodFactory.CreateInstance(targetType);
                var adder    = AdderMethodCache.GetOrAdd(sourceListType, type => new AdderMethodInfo(type));

                foreach (var item in ienumerable)
                {
                    adder.Method.Invoke(instance, new object[] { ConvertTo(item, adder.TypeGenericParameters[0]) });
                }
                return(instance);
            }


            // IList
            if (typeof(IList).IsAssignableFrom(targetType) && ienumerable != null)
            {
                var instance = (IList)MethodFactory.CreateInstance(targetType);
                foreach (var item in ienumerable)
                {
                    instance.Add(item);
                }
                return(instance);
            }

            // Guid
            if (targetType == typeof(Guid))
            {
                var input = value as string;
                if (input != null)
                {
                    return(Guid.Parse(input));
                }

                var bytes = value as byte[];
                if (bytes != null)
                {
                    return(new Guid(bytes));
                }
            }

            // Nullable<T>
            if (targetType.IsNullable())
            {
                var underlyingType = Nullable.GetUnderlyingType(targetType);
                return(Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture));
            }

            return(ConvertObject(sourceType, targetType, value));
        }