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); }
public static SerializerPair TryGetIntrinsicSerializer(TypeInfo typeInfo, Func <Type, SerializerPair> getInstanceSerializer) { if (ReflectionSerializerVerifier.HasIntrinsicNonProtocolMethods(typeInfo)) { var genericArguments = typeInfo.GetGenericArguments(); /* * if (genericArguments.Length == 1) * { * var argument = genericArguments[0]; * var staticRead = SerializerReflectionUtil.GetReadStaticSerializer(typeInfo, argument); * var staticWrite = SerializerReflectionUtil.GetWriteStaticDeserializer(typeInfo); * return SerializerPair.CreateFromMethods(staticRead, staticWrite, getInstanceSerializer(argument)); * } */ if (genericArguments.Length == 0) { var staticRead = SerializerReflectionUtil.GetReadStaticNonProtocolSerializer(typeInfo); var instanceWriter = SerializerReflectionUtil.GetWriteNonProtocolDeserializer(typeInfo); return(SerializerPair.CreateFromNonProtocolMethods(staticRead, instanceWriter)); } return(null); } if (ReflectionSerializerVerifier.HasIntrinsicProtocolMethods(typeInfo)) { var genericArguments = typeInfo.GetGenericArguments(); if (genericArguments.Length == 1) { var argument = genericArguments[0]; var staticRead = SerializerReflectionUtil.GetReadStaticSerializer(typeInfo, argument); var staticWrite = SerializerReflectionUtil.GetWriteStaticDeserializer(typeInfo); return(SerializerPair.CreateFromMethods(staticRead, staticWrite, getInstanceSerializer(argument))); } if (genericArguments.Length == 0) { var staticRead = SerializerReflectionUtil.GetReadStaticSerializer(typeInfo); var staticWrite = SerializerReflectionUtil.GetWriteStaticDeserializer(typeInfo); return(SerializerPair.CreateFromMethods(staticRead, staticWrite)); } return(null); } else if (ReflectionSerializerVerifier.HasIntrinsicFields(typeInfo)) { var readField = typeInfo.GetField("Read", BindingFlags.Public | BindingFlags.Static); var writeField = typeInfo.GetField("Write", BindingFlags.Public | BindingFlags.Static); if (readField == null) { Assertion.Fail($"Invalid intrinsic serializer for type {typeInfo}. Static field 'Read' with type {typeof(CtxReadDelegate<>).ToString(true)} not found"); } if (writeField == null) { Assertion.Fail($"Invalid intrinsic serializer for type {typeInfo}. Static field 'Write' with type {typeof(CtxWriteDelegate<>).ToString(true)} not found"); } var reader = readField.GetValue(null); var writer = writeField.GetValue(null); return(new SerializerPair(reader, writer)); } else if (ReflectionSerializerVerifier.HasIntrinsicAttribute(typeInfo)) { var marshallerType = typeInfo.GetCustomAttribute <RdScalarAttribute>().NotNull().Marshaller; var marshaller = Activator.CreateInstance(marshallerType); return((SerializerPair)ReflectionUtil.InvokeStaticGeneric(typeof(SerializerPair), nameof(SerializerPair.FromMarshaller), typeInfo, marshaller)); } return(null); }