in rd-net/RdFramework.Reflection/ReflectionSerializers.cs [80:163]
public SerializerPair GetOrRegisterSerializerPair(Type type, bool instance = false)
{
lock (myLock)
{
var implementingType = ReflectionSerializerVerifier.GetImplementingType(type.GetTypeInfo()).GetTypeInfo();
var isRdType = implementingType != type;
if (!isRdType && instance && SerializerReflectionUtil.CanBePolymorphic(type))
{
myCatalog.AddType(type);
if (myInstanceSerializers.TryGetValue(type, out var pair))
return pair;
BeforeCreation.Fire(type);
if (myInstanceSerializers.TryGetValue(type, out pair))
return pair;
return GetPolymorphic(type);
}
if (!myStaticSerializers.TryGetValue(type, out var serializerPair))
{
using var info = new FirstChanceExceptionInterceptor.ThreadLocalDebugInfo(type);
myCatalog.AddType(type);
BeforeCreation.Fire(type);
if (myStaticSerializers.TryGetValue(type, out serializerPair))
return serializerPair;
if (Mode.IsAssertion) myCurrentSerializersChain.Enqueue(type);
try
{
myStaticSerializers.Add(type, null!);
if (isRdType)
{
var builtIn = BuiltInSerializers.TryGet(implementingType, t => GetOrRegisterSerializerPair(t, true));
Assertion.AssertNotNull(builtIn, "Unable to get built in serializer for type {0}, thought it should be implemented for Rd-types.", type);
var pair = SerializerReflectionUtil.ConvertPair(builtIn, type);
myStaticSerializers[type] = pair;
}
else if (ReflectionSerializerVerifier.IsScalar(type))
{
myStaticSerializers[type] = CreateScalar(type, instance);
}
else if (BuiltInSerializers.Has(type.GetTypeInfo()))
{
var builtIn = BuiltInSerializers.TryGet(
type.GetTypeInfo(),
t => GetOrRegisterSerializerPair(t, true));
Assertion.AssertNotNull(builtIn, "Unable to get built in serializer for type {0}, thought API detect the presense of it. Probably it was only partially implemented",
type);
myStaticSerializers[type] = builtIn;
}
else
{
ReflectionUtil.InvokeGenericThis(this, nameof(RegisterModelSerializer), type);
}
}
finally
{
if (Mode.IsAssertion) myCurrentSerializersChain.Dequeue();
}
if (!myStaticSerializers.TryGetValue(type, out serializerPair))
{
throw new KeyNotFoundException($"Unable to register type {type.ToString(true)}: serializer can't be found");
}
}
if (Mode.IsAssertion && serializerPair == null)
Assertion.Fail(
$"Unable to create serializer for {type.ToString(true)}: circular dependency detected: {Join(" -> ", myCurrentSerializersChain.Select(t => t.ToString(true)).ToArray())}");
else
Assertion.AssertNotNull(serializerPair,
$"Unable to register type: {type.ToString(true)}, undetected circular dependency. Enable Mode.IsAssertion to get the cycle.");
return serializerPair;
}
}