public KeyValuePairPartBuilder(Type type, PartDefinition partDefinition, IPartResolver resolver)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }

            if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(KeyValuePair <,>))
            {
                throw new ArgumentException("type must be a KeyValuePair<,>", "type");
            }

            if (type.IsGenericTypeDefinition)
            {
                throw new ArgumentException("The type parameters of type are not defined", "type");
            }

            _type = type;
            var typeArgs = _type.GetGenericArguments();

            _keyType      = typeArgs[0];
            _valueType    = typeArgs[1];
            _keyBuilder   = resolver.GetPartBuilder(_keyType, partDefinition, true);
            _valueBuilder = resolver.GetPartBuilder(_valueType, partDefinition, true);
            _ctor         = _type.GetConstructor(new[] { _keyType, _valueType });
            Debug.Assert(_ctor != null, "Couldn't find KeyValuePair constructor");
        }
예제 #2
0
 public NullablePartBuilder(Type nullableType, PartDefinition partDefinition, IPartResolver resolver)
 {
     if (nullableType.GetGenericTypeDefinition() != typeof(Nullable <>))
     {
         throw new ArgumentException(string.Format("{0} is not a Nullable<T>", nullableType), "nullableType");
     }
     _type         = nullableType;
     _innerType    = _type.GetGenericArguments()[0];
     _ctor         = _type.GetConstructor(new[] { _innerType });
     _innerBuilder = resolver.GetPartBuilder(_innerType, partDefinition, true);
 }
예제 #3
0
        public static IPartBuilder GetPartBuilder(this IPartResolver resolver, Type type, PartDefinition partDefinition, bool throwIfUnresolvable)
        {
            var result = resolver.GetPartBuilder(type, partDefinition);

            if (result == null && throwIfUnresolvable)
            {
                throw new NotSupportedException(string.Format(
                                                    "Property - {0} cannot be serialized by the auto-serialization framework. PartResolver - {1}",
                                                    partDefinition,
                                                    resolver));
            }

            return(result);
        }
예제 #4
0
        public ArrayPartBuilder(Type arrayType, PartDefinition partDefinition, IPartResolver resolver)
        {
            if (!arrayType.IsArray)
            {
                throw new ArgumentException("arrayType is not an array", "arrayType");
            }

            if (arrayType.GetArrayRank() != 1)
            {
                throw new NotSupportedException("Multi-dimensional arrays are not supported by this class.");
            }

            _elementType    = arrayType.GetElementType();
            _elementBuilder = resolver.GetPartBuilder(_elementType, partDefinition, true);
        }
예제 #5
0
        public EnumPartBuilder(Type type, PartDefinition partDefinition, IPartResolver resolver)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (!type.IsEnum)
            {
                throw new ArgumentException("type must be an enumeration", "type");
            }

            _type           = type;
            _underlyingType = Enum.GetUnderlyingType(type);
            _innerBuilder   =
                _underlyingType == typeof(int)
                ? new PrimitivePartBuilder(typeof(int), "ReadVarInt32", "WriteVarInt32")
                                : resolver.GetPartBuilder(_underlyingType, partDefinition, true);
        }
예제 #6
0
        public CollectionPartBuilder(Type collectionType, Type elementType, PartDefinition partDefinition, IPartResolver resolver, Type underlyingType)
        {
            if (collectionType == null)
            {
                throw new ArgumentNullException("collectionType");
            }
            if (elementType == null)
            {
                throw new ArgumentNullException("elementType");
            }
            if (partDefinition == null)
            {
                throw new ArgumentNullException("partDefinition");
            }
            if (resolver == null)
            {
                throw new ArgumentNullException("resolver");
            }

            _collectionType = collectionType;
            _elementType    = elementType;
            _innerBuilder   = resolver.GetPartBuilder(_elementType, partDefinition, true);

            if (_innerBuilder == null)
            {
                throw new NotSupportedException(string.Format("Type '{0}' cannot be serialized", elementType));
            }

            var interfaceType = typeof(ICollection <>).MakeGenericType(elementType);

            if (!interfaceType.IsAssignableFrom(collectionType))
            {
                throw new ArgumentException(string.Format(
                                                "collectionType '{0}' is not assignable to '{1}'",
                                                collectionType.Name,
                                                interfaceType.Name),
                                            "collectionType");
            }

            _getCount = _collectionType.GetBestCallableOverride(interfaceType.ResolveProperty("Count").GetGetMethod());
            _add      = _collectionType.GetBestCallableOverride(interfaceType.ResolveMethod("Add", new[] { elementType }));
            _contains = _collectionType.GetBestCallableOverride(interfaceType.ResolveMethod("Contains", elementType));

            const BindingFlags bindingFlags =
                BindingFlags.CreateInstance
                | BindingFlags.Public
                | BindingFlags.NonPublic
                | BindingFlags.Instance;

            _ctor     = underlyingType.GetConstructor(bindingFlags, null, new[] { typeof(int) }, null);
            _ctorType = CtorType.Capacity;
            if (_ctor == null || _ctor.GetParameters()[0].Name != "capacity")
            {
                _ctor     = underlyingType.GetConstructor(bindingFlags, null, Type.EmptyTypes, null);
                _ctorType = CtorType.Default;
            }

            if (_ctor == null)
            {
                throw new ArgumentException("collectionType='" + collectionType.Name + "' does not define .ctor(int capacity) or .ctor()", "collectionType");
            }
        }
예제 #7
0
 public CollectionPartBuilder(Type collectionType, Type elementType, PartDefinition partDefinition, IPartResolver resolver)
     : this(collectionType, elementType, partDefinition, resolver, collectionType)
 {
 }
예제 #8
0
        private static IEnumerable <KeyValuePair <Type, PartBuilderFactory> > GetGenericPartFactories(int frameworkVersion, IPartResolver resolver)
        {
            yield return(new KeyValuePair <Type, PartBuilderFactory>(
                             typeof(Nullable <>),
                             (type, partDef) => new NullablePartBuilder(type, partDef, resolver)));

            yield return(new KeyValuePair <Type, PartBuilderFactory>(
                             typeof(KeyValuePair <,>),
                             (type, partDef) => new KeyValuePairPartBuilder(type, partDef, resolver)));

            PartBuilderFactory collectionFactory = (type, partDef) => new CollectionPartBuilder(type, type.GetGenericArguments()[0], partDef, resolver);

            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(List <>), collectionFactory));

            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(Collection <>), collectionFactory));

            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(LinkedList <>), collectionFactory));

            //yield return new KeyValuePair<Type, PartBuilderFactory>(typeof(Queue<>), collectionFactory);
            //yield return new KeyValuePair<Type, PartBuilderFactory>(typeof(Stack<>), collectionFactory);
            collectionFactory = (type, partDef) =>
            {
                var elementType    = type.GetGenericArguments().First <Type>();
                var underlyingType = typeof(List <>).MakeGenericType(elementType);
                return(new CollectionPartBuilder(type, elementType, partDef, resolver, underlyingType));
            };
            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(IList <>), collectionFactory));

            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(ICollection <>), collectionFactory));

            PartBuilderFactory dictionaryFactory = (type, partDef) =>
            {
                var genericArgs = type.GetGenericArguments();
                var elementType = typeof(KeyValuePair <,>).MakeGenericType(genericArgs[0], genericArgs[1]);
                return(new CollectionPartBuilder(type, elementType, partDef, resolver));
            };

            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(Dictionary <,>), dictionaryFactory));

            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(SortedDictionary <,>), dictionaryFactory));

            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(SortedList <,>), dictionaryFactory));

            dictionaryFactory = (type, partDef) =>
            {
                var genericArgs    = type.GetGenericArguments();
                var elementType    = typeof(KeyValuePair <,>).MakeGenericType(genericArgs[0], genericArgs[1]);
                var underlyingType = typeof(Dictionary <,>).MakeGenericType(genericArgs[0], genericArgs[1]);
                return(new CollectionPartBuilder(type, elementType, partDef, resolver, underlyingType));
            };
            yield return(new KeyValuePair <Type, PartBuilderFactory>(typeof(IDictionary <,>), dictionaryFactory));
        }
예제 #9
0
        public static SerializableStructPartBuilder TryCreate(Type type, PartDefinition partDefinition, IPartResolver resolver)
        {
            var attribute = Attribute
                            .GetCustomAttributes(type, typeof(SerializableStructAttribute), false)
                            .Cast <SerializableStructAttribute>()
                            .FirstOrDefault <SerializableStructAttribute>();

            if (attribute == null)
            {
                return(null);
            }

            var targetType = attribute.TargetType;

            if (!type.IsValueType)
            {
                throw new BarfException(string.Format(
                                            "{0}(typeof({1})) is invalid on type {2}. {2} must be a value type.",
                                            typeof(SerializableStructAttribute).Name,
                                            targetType,
                                            type), type, null);
            }

            if (!targetType.IsPrimitive)
            {
                throw new BarfException(string.Format(
                                            "{0}(typeof({1})) is invalid. {1} must be primitive type.",
                                            typeof(SerializableStructAttribute).Name,
                                            targetType.Name),
                                        type,
                                        null);
            }

            var possibleMethods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly)
                                  .Where <MethodInfo>(m => m.IsSpecialName)
                                  .Where <MethodInfo>(m => m.Name == "op_Explicit" || m.Name == "op_Implicit")
                                  .Where <MethodInfo>(m => !m.IsGenericMethodDefinition);

            var result = new SerializableStructPartBuilder
            {
                _targetType        = targetType,
                _toPrimitiveMethod = possibleMethods
                                     .Where <MethodInfo>(m => m.ReturnType == targetType)
                                     .Where <MethodInfo>(m =>
                {
                    var p = m.GetParameters();
                    return(p.Length == 1 && p[0].ParameterType == type);
                })
                                     .FirstOrDefault <MethodInfo>(),
                _fromPrimitiveMethod = possibleMethods
                                       .Where <MethodInfo>(m => m.ReturnType == type)
                                       .Where <MethodInfo>(m =>
                {
                    var p = m.GetParameters();
                    return(p.Length == 1 && p[0].ParameterType == targetType);
                })
                                       .FirstOrDefault <MethodInfo>(),
                _innerBuilder = resolver.GetPartBuilder(targetType, partDefinition, true)
            };

            if (result._toPrimitiveMethod == null || result._fromPrimitiveMethod == null)
            {
                throw new BarfException(string.Format(
                                            "{0}(typeof({1})) is invalid on type {2}. {2} must define an implicit or explicit conversion operator to type {1}.",
                                            typeof(SerializableStructAttribute).Name,
                                            targetType,
                                            type), type, null);
            }

            return(result);
        }
예제 #10
0
 public static IPartBuilder GetPartBuilder(this IPartResolver resolver, PartDefinition partDefinition, bool throwIfUnresolvable)
 {
     return(resolver.GetPartBuilder(partDefinition.Type, partDefinition, throwIfUnresolvable));
 }
예제 #11
0
 public static IPartBuilder GetPartBuilder(this IPartResolver resolver, PartDefinition partDefinition)
 {
     return(resolver.GetPartBuilder(partDefinition.Type, partDefinition));
 }