/// <summary> /// Gets the object serializer corresponding to a specific type. /// </summary> /// <param name="Type">Type of object to serialize.</param> /// <returns>Object Serializer</returns> public async Task <IObjectSerializer> GetObjectSerializer(Type Type) { IObjectSerializer Result; TypeInfo TI = Type.GetTypeInfo(); lock (this.synchObj) { if (this.serializers.TryGetValue(Type, out Result)) { return(Result); } if (TI.IsEnum) { Result = new EnumSerializer(Type); } else if (Type.IsArray) { Type ElementType = Type.GetElementType(); Type T = Types.GetType(typeof(ByteArraySerializer).FullName.Replace("ByteArray", "Array")); Type SerializerType = T.MakeGenericType(new Type[] { ElementType }); Result = (IObjectSerializer)Activator.CreateInstance(SerializerType, this.context); } else if (TI.IsGenericType) { Type GT = Type.GetGenericTypeDefinition(); if (GT == typeof(Nullable <>)) { Type NullableType = Type.GenericTypeArguments[0]; if (NullableType.GetTypeInfo().IsEnum) { Result = new Serialization.NullableTypes.NullableEnumSerializer(NullableType); } else { Result = null; } } else { Result = null; } } else { Result = null; } if (!(Result is null)) { this.serializers[Type] = Result; this.serializerAdded.Set(); return(Result); } } try { #if NETSTANDARD1_5 Result = await ObjectSerializer.Create(Type, this.context, this.compiled); #else Result = await ObjectSerializer.Create(Type, this.context); #endif await Result.Init(); lock (this.synchObj) { this.serializers[Type] = Result; this.serializerAdded.Set(); } } catch (FileLoadException ex) { // Serializer in the process of being generated from another task or thread. while (true) { if (!this.serializerAdded.WaitOne(1000)) { ExceptionDispatchInfo.Capture(ex).Throw(); } lock (this.synchObj) { if (this.serializers.TryGetValue(Type, out Result)) { return(Result); } } } } return(Result); }