예제 #1
0
        /// <summary>
        /// Return static serializers for type
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public SerializerPair GetOrCreate(Type type)
        {
            if (myStaticSerializers.TryGetValue(type, out var pair))
            {
                return(pair);
            }

            if (myBlackListChecker(type))
            {
                Assertion.Fail($"Attempt to create serializer for black-listed type: {type.ToString(true)}");
            }

            var result = CreateSerializer(type);

            myStaticSerializers[type] = result;
            return(result);

            SerializerPair CreateSerializer(Type t)
            {
                var typeInfo = t.GetTypeInfo();

                var intrinsic = Intrinsic.TryGetIntrinsicSerializer(typeInfo, GetInstanceSerializer);

                if (intrinsic != null)
                {
                    myTypesCatalog.AddType(type);
                    return(intrinsic);
                }

                if (IsList(t))
                {
                    var genericTypeArgument        = t.GetGenericArguments()[0];
                    var argumentTypeSerializerPair = GetInstanceSerializer(genericTypeArgument);
                    return((SerializerPair)ReflectionUtil.InvokeStaticGeneric(typeof(CollectionSerializers), nameof(CollectionSerializers.CreateListSerializerPair), genericTypeArgument, argumentTypeSerializerPair));
                }
                else if (IsDictionary(t) || IsReadOnlyDictionary(t))
                {
                    var typeArguments          = t.GetGenericArguments();
                    var tkey                   = typeArguments[0];
                    var tvalue                 = typeArguments[1];
                    var keySerializer          = GetInstanceSerializer(tkey);
                    var valueSerializer        = GetInstanceSerializer(tvalue);
                    var serializersFactoryName = IsReadOnlyDictionary(t) ? nameof(CollectionSerializers.CreateReadOnlyDictionarySerializerPair) : nameof(CollectionSerializers.CreateDictionarySerializerPair);
                    return((SerializerPair)ReflectionUtil.InvokeStaticGeneric2(typeof(CollectionSerializers), serializersFactoryName, tkey, tvalue, keySerializer, valueSerializer));
                }
                else if (t.IsArray)
                {
                    return((SerializerPair)ReflectionUtil.InvokeGenericThis(this, nameof(CreateArraySerializer), t.GetElementType()));
                }
                else if (t.IsEnum)
                {
                    var serializer = ReflectionUtil.InvokeGenericThis(this, nameof(CreateEnumSerializer), t);
                    return((SerializerPair)serializer);
                }
                else if (ReflectionSerializerVerifier.IsValueTuple(typeInfo))
                {
                    return((SerializerPair)ReflectionUtil.InvokeGenericThis(this, nameof(CreateValueTupleSerializer), type));
                }
                else if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    var genericTypeArgument = typeInfo.GetGenericArguments()[0];
                    var nullableSerializer  = (SerializerPair)ReflectionUtil.InvokeGenericThis(this, nameof(RegisterNullable), genericTypeArgument);
                    return(nullableSerializer);
                    // return CreateGenericSerializer(member, typeInfo, implementingType, implementingTypeInfo);
                }
                else
                {
                    myTypesCatalog.AddType(type);
                    var serializer = ReflectionUtil.InvokeGenericThis(this, nameof(CreateCustomScalar), t);
                    return((SerializerPair)serializer);
                }
            }
        }