| File: System\Text\Json\Serialization\Metadata\JsonTypeInfoResolver.cs | Web Access |
| Project: src\runtime\src\libraries\System.Text.Json\src\System.Text.Json.csproj (System.Text.Json) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. namespace System.Text.Json.Serialization.Metadata { /// <summary> /// Contains utilities and combinators acting on <see cref="IJsonTypeInfoResolver"/>. /// </summary> public static class JsonTypeInfoResolver { /// <summary> /// Combines multiple <see cref="IJsonTypeInfoResolver"/> sources into one. /// </summary> /// <param name="resolvers">Sequence of contract resolvers to be queried for metadata.</param> /// <returns>A <see cref="IJsonTypeInfoResolver"/> combining results from <paramref name="resolvers"/>.</returns> /// <exception cref="ArgumentException"><paramref name="resolvers"/> is null.</exception> /// <remarks> /// The combined resolver will query each of <paramref name="resolvers"/> in the specified order, /// returning the first result that is non-null. If all <paramref name="resolvers"/> return null, /// then the combined resolver will also return <see langword="null"/>. /// /// Can be used to combine multiple <see cref="JsonSerializerContext"/> sources, /// which typically define contract metadata for small subsets of types. /// It can also be used to fall back to <see cref="DefaultJsonTypeInfoResolver"/> wherever necessary. /// </remarks> public static IJsonTypeInfoResolver Combine(params IJsonTypeInfoResolver?[] resolvers) { ArgumentNullException.ThrowIfNull(resolvers); return Combine((ReadOnlySpan<IJsonTypeInfoResolver?>)resolvers); } /// <summary> /// Combines multiple <see cref="IJsonTypeInfoResolver"/> sources into one. /// </summary> /// <param name="resolvers">Sequence of contract resolvers to be queried for metadata.</param> /// <returns>A <see cref="IJsonTypeInfoResolver"/> combining results from <paramref name="resolvers"/>.</returns> /// <remarks> /// The combined resolver will query each of <paramref name="resolvers"/> in the specified order, /// returning the first result that is non-null. If all <paramref name="resolvers"/> return null, /// then the combined resolver will also return <see langword="null"/>. /// /// Can be used to combine multiple <see cref="JsonSerializerContext"/> sources, /// which typically define contract metadata for small subsets of types. /// It can also be used to fall back to <see cref="DefaultJsonTypeInfoResolver"/> wherever necessary. /// </remarks> public static IJsonTypeInfoResolver Combine(params ReadOnlySpan<IJsonTypeInfoResolver?> resolvers) { var resolverChain = new JsonTypeInfoResolverChain(); foreach (IJsonTypeInfoResolver? resolver in resolvers) { resolverChain.AddFlattened(resolver); } return resolverChain.Count == 1 ? resolverChain[0] : resolverChain; } /// <summary> /// Creates a resolver applies modifications to the metadata generated by the source <paramref name="resolver"/>. /// </summary> /// <param name="resolver">The source resolver generating <see cref="JsonTypeInfo"/> metadata.</param> /// <param name="modifier">The delegate modifying non-null <see cref="JsonTypeInfo"/> results.</param> /// <returns>A new <see cref="IJsonTypeInfoResolver"/> instance applying the modifications.</returns> /// <remarks> /// This method is closely related to <see cref="DefaultJsonTypeInfoResolver.Modifiers"/> property /// extended to arbitrary <see cref="IJsonTypeInfoResolver"/> instances. /// </remarks> public static IJsonTypeInfoResolver WithAddedModifier(this IJsonTypeInfoResolver resolver, Action<JsonTypeInfo> modifier) { ArgumentNullException.ThrowIfNull(resolver); ArgumentNullException.ThrowIfNull(modifier); return resolver is JsonTypeInfoResolverWithAddedModifiers resolverWithModifiers ? resolverWithModifiers.WithAddedModifier(modifier) : new JsonTypeInfoResolverWithAddedModifiers(resolver, new[] { modifier }); } /// <summary> /// Gets a resolver that returns null <see cref="JsonTypeInfo"/> for every type. /// </summary> internal static IJsonTypeInfoResolver Empty { get; } = new EmptyJsonTypeInfoResolver(); /// <summary> /// Indicates whether the metadata generated by the current resolver /// are compatible with the run time specified <see cref="JsonSerializerOptions"/>. /// </summary> internal static bool IsCompatibleWithOptions(this IJsonTypeInfoResolver? resolver, JsonSerializerOptions options) => resolver is IBuiltInJsonTypeInfoResolver bir && bir.IsCompatibleWithOptions(options); } /// <summary> /// A <see cref="IJsonTypeInfoResolver"/> that returns null for all inputs. /// </summary> internal sealed class EmptyJsonTypeInfoResolver : IJsonTypeInfoResolver, IBuiltInJsonTypeInfoResolver { public JsonTypeInfo? GetTypeInfo(Type type, JsonSerializerOptions options) => null; public bool IsCompatibleWithOptions(JsonSerializerOptions _) => true; } /// <summary> /// Implemented by the built-in converters to avoid rooting /// unused resolver dependencies in the context of the trimmer. /// </summary> internal interface IBuiltInJsonTypeInfoResolver { /// <summary> /// Indicates whether the metadata generated by the current resolver /// are compatible with the run time specified <see cref="JsonSerializerOptions"/>. /// </summary> bool IsCompatibleWithOptions(JsonSerializerOptions options); } }