private SerializerPair GetOrRegisterStaticSerializerInternal(Type type, bool instance)
        {
            if (ReflectionSerializerVerifier.IsScalar(type))
            {
                return(GetOrCreateScalar(type, instance));
            }

            // RdModels only
            if (!mySerializers.TryGetValue(type, out var serializerPair))
            {
#if JET_MODE_ASSERT
                myCurrentSerializersChain.Enqueue(type);
#endif

                using (new FirstChanceExceptionInterceptor.ThreadLocalDebugInfo(type))
                {
                    if (ReflectionSerializerVerifier.HasIntrinsicFields(type.GetTypeInfo()))
                    {
                        mySerializers.Add(type, Intrinsic.TryGetIntrinsicSerializer(
                                              type.GetTypeInfo(),
                                              _ => throw new InvalidOperationException("Generic models are not supported")));
                    }
                    else
                    {
                        ReflectionUtil.InvokeGenericThis(this, nameof(RegisterModelSerializer), type);
                    }
                }

#if JET_MODE_ASSERT
                myCurrentSerializersChain.Dequeue();
#endif

                if (!mySerializers.TryGetValue(type, out serializerPair))
                {
                    throw new KeyNotFoundException($"Unable to register type {type.ToString(true)}: serializer can't be found");
                }
            }

            Assertion.AssertNotNull(serializerPair, $"Unable to register type: {type.ToString(true)}, undetected circular dependency.");

            if (instance && !type.IsSealed)
            {
                return(GetPolymorphic(type));
            }

            return(serializerPair);
        }
Exemple #2
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);
                }
            }
        }