/// <summary> /// Configures <see cref="JsonSerializerOptions"/> and adds <see cref="JsonConverter"/>s for <i>Aqua</i> and <i>Remote.Linq</i> types. /// </summary> /// <param name="options">Json serializer options to be ammended.</param> /// <param name="knownTypesRegistry">Type registry to control types for deserialization of <see cref="DynamicObject"/>s.</param> public static JsonSerializerOptions ConfigureRemoteLinq(this JsonSerializerOptions options, KnownTypesRegistry?knownTypesRegistry) { options.AssertNotNull(nameof(options)); knownTypesRegistry ??= KnownTypesRegistry.Default; RegisterKnownTypes(knownTypesRegistry); options.ConfigureAqua(knownTypesRegistry); if (!options.Converters.Any(x => x is VariableQueryArgumentConverter)) { options.Converters.Add(new VariableQueryArgumentConverter(knownTypesRegistry)); } if (!options.Converters.Any(x => x is VariableQueryArgumentListConverter)) { options.Converters.Add(new VariableQueryArgumentListConverter(knownTypesRegistry)); } // Workaround: there seems to be no proper way to deal with converters for abtract base types, // hence we register for abstract as well as non-abstract types. typeof(Expression).Assembly .GetTypes() .Where(x => !x.IsAbstract) .Where(typeof(Expression).IsAssignableFrom) .RegisterJsonConverter(typeof(ExpressionConverter <>), options, knownTypesRegistry); if (!options.Converters.Any(x => x is ExpressionConverter <Expression>)) { options.Converters.Add(new ExpressionConverter <Expression>(knownTypesRegistry, true)); } typeof(Expression).Assembly .GetTypes() .Where(x => x.IsClass && !x.IsAbstract && !x.IsGenericType) .Where(x => x.GetCustomAttributes(typeof(DataContractAttribute), false).Length > 0) .RegisterJsonConverter(typeof(ObjectConverter <>), options, knownTypesRegistry); if (!options.Converters.Any(x => x is ObjectConverter <MemberBinding>)) { options.Converters.Add(new ObjectConverter <MemberBinding>(knownTypesRegistry, true)); } return(options); }