diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs index 9b5197a4b95..a8444286571 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Configuration/ElasticsearchClientSettings.cs @@ -9,7 +9,7 @@ using System.Linq.Expressions; using System.Reflection; using System.Runtime.InteropServices; - +using System.Text.Json.Serialization.Metadata; using Elastic.Clients.Elasticsearch.Esql; using Elastic.Clients.Elasticsearch.Requests; using Elastic.Clients.Elasticsearch.Serialization; @@ -86,10 +86,12 @@ public ElasticsearchClientSettings(InMemoryRequestInvoker inMemoryTransportClien public ElasticsearchClientSettings( NodePool nodePool, IRequestInvoker requestInvoker, - SourceSerializerFactory sourceSerializer, - IPropertyMappingProvider propertyMappingProvider) : base(nodePool, requestInvoker, sourceSerializer, propertyMappingProvider) + SourceSerializerFactory? sourceSerializer, + IPropertyMappingProvider? propertyMappingProvider + ) : base(nodePool, requestInvoker, sourceSerializer, propertyMappingProvider) { } + } /// @@ -121,9 +123,10 @@ public abstract class ElasticsearchClientSettingsBase : protected ElasticsearchClientSettingsBase( NodePool nodePool, - IRequestInvoker requestInvoker, + IRequestInvoker? requestInvoker, ElasticsearchClientSettings.SourceSerializerFactory? sourceSerializerFactory, - IPropertyMappingProvider propertyMappingProvider) + IPropertyMappingProvider? propertyMappingProvider + ) : base(nodePool, requestInvoker, null, ElasticsearchClientProductRegistration.DefaultForElasticsearchClientsElasticsearch) { var requestResponseSerializer = new DefaultRequestResponseSerializer(this); @@ -131,11 +134,12 @@ protected ElasticsearchClientSettingsBase( UseThisRequestResponseSerializer = requestResponseSerializer; + _propertyMappingProvider = propertyMappingProvider ?? new DefaultPropertyMappingProvider(); _sourceSerializer = sourceSerializerFactory?.Invoke(sourceSerializer, this) ?? sourceSerializer; - _propertyMappingProvider = propertyMappingProvider ?? sourceSerializer as IPropertyMappingProvider ?? new DefaultPropertyMappingProvider(); _defaultFieldNameInferrer = _sourceSerializer.TryGetJsonSerializerOptions(out var options) ? p => options.PropertyNamingPolicy?.ConvertName(p) ?? p : p => p.ToCamelCase(); + _defaultIndices = new FluentDictionary(); _defaultRelationNames = new FluentDictionary(); _inferrer = new Inferrer(this); @@ -394,9 +398,12 @@ public abstract class ConnectionConfigurationBase : { private bool _includeServerStackTraceOnError; - protected ConnectionConfigurationBase(NodePool nodePool, IRequestInvoker requestInvoker, + protected ConnectionConfigurationBase( + NodePool nodePool, + IRequestInvoker? requestInvoker, Serializer? serializer, - ProductRegistration registration = null) + ProductRegistration? registration = null + ) : base(nodePool, requestInvoker, serializer, registration ?? new ElasticsearchProductRegistration(typeof(ElasticsearchClient))) { UserAgent(ConnectionConfiguration.DefaultUserAgent); diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Id.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Id.cs index be299083f95..2940f91cbcd 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Id.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/Id.cs @@ -8,7 +8,7 @@ using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; - +using Elastic.Clients.Elasticsearch.Json; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/IdConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/IdConverter.cs index a6728cab761..133a3b51659 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/IdConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/Id/IdConverter.cs @@ -9,9 +9,9 @@ using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Json; -internal sealed class IdConverter : JsonConverter +public sealed class IdConverter : JsonConverter { private IElasticsearchClientSettings? _settings; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/Routing.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/Routing.cs index 22caa1b9cb0..0ce24b92387 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/Routing.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/Routing.cs @@ -9,7 +9,7 @@ using System.Linq; using System.Text.Json; using System.Text.Json.Serialization; - +using Elastic.Clients.Elasticsearch.Json; using Elastic.Transport; namespace Elastic.Clients.Elasticsearch; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/RoutingConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/RoutingConverter.cs index f7b4d0c6efa..83ef02269ec 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/RoutingConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Core/Infer/JoinFieldRouting/RoutingConverter.cs @@ -8,9 +8,9 @@ using System.Text.Json.Serialization; using Elastic.Clients.Elasticsearch.Serialization; -namespace Elastic.Clients.Elasticsearch; +namespace Elastic.Clients.Elasticsearch.Json; -internal sealed class RoutingConverter : JsonConverter +public sealed class RoutingConverter : JsonConverter { private IElasticsearchClientSettings _settings; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Next/ContextProvider.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Next/ContextProvider.cs index 8e0f373b4de..84d1820993e 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Next/ContextProvider.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Next/ContextProvider.cs @@ -33,11 +33,11 @@ public ContextProvider(TContext context) /// If no for is registered to the given /// instance. /// + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public static TContext GetContext(JsonSerializerOptions options) { -#pragma warning disable IL2026, IL3050 if (options.GetConverter(typeof(Marker)) is not Converter provider) -#pragma warning restore IL2026, IL3050 { throw new InvalidOperationException($"No context provider for type '{typeof(TContext).Name}' is " + $"registered for the given 'JsonSerializerOptions' instance."); @@ -55,11 +55,11 @@ public static TContext GetContext(JsonSerializerOptions options) /// if the context was successfully retrieved from the given /// or , if not. /// + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public static bool TryGetContext(JsonSerializerOptions options, [MaybeNullWhen(false)] out TContext context) { -#pragma warning disable IL2026, IL3050 if (options.GetConverter(typeof(Marker)) is not Converter provider) -#pragma warning restore IL2026, IL3050 { context = default; return false; diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Next/JsonSerializerOptionsExtensions.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Next/JsonSerializerOptionsExtensions.cs index d161c05b17f..a94097a25ed 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Next/JsonSerializerOptionsExtensions.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Next/JsonSerializerOptionsExtensions.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; - +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Text.Json.Serialization; @@ -13,6 +13,8 @@ namespace Elastic.Clients.Elasticsearch.Serialization; internal static partial class JsonSerializerOptionsExtensions { + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static JsonConverter GetConverter(this JsonSerializerOptions options, Type? markerType) { @@ -20,13 +22,9 @@ public static JsonConverter GetConverter(this JsonSerializerOptions option // to directly use converters like we do. // When getting a default generic converter from `JsonSerializerOptions` that are not read-only, a // `NotSupportedException` is thrown as soon as we call `converter.Read()` or `converter.Write()`. -#pragma warning disable IL2026, IL3050 options.MakeReadOnly(true); -#pragma warning restore IL2026, IL3050 -#pragma warning disable IL2026, IL3050 var rawConverter = options.GetConverter(markerType ?? typeof(T)); -#pragma warning restore IL2026, IL3050 var converter = (JsonConverter)(rawConverter is IMarkerTypeConverter markerTypeConverter ? markerTypeConverter.WrappedConverter @@ -35,6 +33,8 @@ public static JsonConverter GetConverter(this JsonSerializerOptions option return converter; } + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static TContext GetContext(this JsonSerializerOptions options) { diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Next/ObjectToInferredTypesConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Next/ObjectToInferredTypesConverter.cs index 0a0c0f7dd0a..f6e77bc8ccd 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Next/ObjectToInferredTypesConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Next/ObjectToInferredTypesConverter.cs @@ -3,14 +3,16 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; namespace Elastic.Clients.Elasticsearch.Serialization; -internal sealed class ObjectToInferredTypesConverter : - JsonConverter +internal sealed class ObjectToInferredTypesConverter : JsonConverter { + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return reader.TokenType switch @@ -26,12 +28,11 @@ JsonTokenType.String when reader.TryGetDateTimeOffset(out var value) => value, }; } + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) { // TODO: Match `SourceMarker` values and delegate to the `SourceSerializer`. - -#pragma warning disable IL2026, IL3050 JsonSerializer.Serialize(writer, value, value.GetType(), options); -#pragma warning restore IL2026, IL3050 } } diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Next/SourceConverter.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Next/SourceConverter.cs index f52b062454f..b89de8d84f1 100644 --- a/src/Elastic.Clients.Elasticsearch/_Shared/Next/SourceConverter.cs +++ b/src/Elastic.Clients.Elasticsearch/_Shared/Next/SourceConverter.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text.Json; using System.Text.Json.Serialization; @@ -50,12 +51,11 @@ public override bool CanConvert(Type typeToConvert) typeToConvert.GetGenericTypeDefinition() == typeof(SourceMarker<>); } + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) { var args = typeToConvert.GetGenericArguments(); -#pragma warning disable IL3050 // SourceMarker static constructor roots SourceMarkerConverter. - var converter = (JsonConverter)Activator.CreateInstance( typeof(SourceMarkerConverter<>).MakeGenericType(args[0]), BindingFlags.Instance | BindingFlags.Public, @@ -63,14 +63,11 @@ public override bool CanConvert(Type typeToConvert) args: [settings], culture: null)!; -#pragma warning restore IL3050 - return converter; } } -internal sealed class SourceConverter : - JsonConverter +internal sealed class SourceConverter : JsonConverter { private readonly IElasticsearchClientSettings _settings; @@ -79,11 +76,15 @@ public SourceConverter(IElasticsearchClientSettings settings) _settings = settings; } + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { return _settings.SourceSerializer.Deserialize(ref reader); } + [UnconditionalSuppressMessage("AOT", "IL3050:Calling members annotated with 'RequiresDynamicCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] + [UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute'", Justification = "Always using explicit TypeInfoResolver")] public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options) { _settings.SourceSerializer.Serialize(value, writer); diff --git a/src/Playground/Person.cs b/src/Playground/Person.cs index 62f758eab7d..e1fcf7bcffe 100644 --- a/src/Playground/Person.cs +++ b/src/Playground/Person.cs @@ -3,27 +3,31 @@ // See the LICENSE file in the project root for more information. using System.Runtime.Serialization; +using System.Text.Json.Serialization; using Elastic.Clients.Elasticsearch; -using Elastic.Clients.Elasticsearch.QueryDsl; +using Playground; namespace Playground { + [JsonSerializable(typeof(Person))] + internal partial class PlaygroundJsonSerializerContext : JsonSerializerContext; + public class Person { public int Id { get; set; } - [System.Text.Json.Serialization.JsonPropertyName("id2")] + [JsonPropertyName("id2")] public Guid SecondaryId { get; set; } = Guid.NewGuid(); public string? FirstName { get; init; } public string? LastName { get; init; } public int? Age { get; init; } - public bool IsDeleted { get; init; } + public bool IsDeleted { get; init; } public Routing? Routing { get; init; } public Id Idv3 => "testing"; //public Guid Routing { get; init; } = Guid.NewGuid(); - [System.Text.Json.Serialization.JsonIgnore] + [JsonIgnore] public string? Email { get; init; } [DataMember(Name = "STEVE")] @@ -31,8 +35,6 @@ public class Person public string Data { get; init; } = "NOTHING"; public DateTimeKind Enum { get; init; } - - public Query? Q { get; init; } } public class PersonV3 @@ -40,3 +42,6 @@ public class PersonV3 public Guid SecondaryId { get; set; } = Guid.NewGuid(); } } + + + diff --git a/src/Playground/Playground.csproj b/src/Playground/Playground.csproj index 06e0eb5b9c0..75df2119aef 100644 --- a/src/Playground/Playground.csproj +++ b/src/Playground/Playground.csproj @@ -13,7 +13,6 @@ - diff --git a/src/Playground/Program.cs b/src/Playground/Program.cs index 5990a7f8ed2..402bd448a62 100644 --- a/src/Playground/Program.cs +++ b/src/Playground/Program.cs @@ -3,14 +3,18 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics.CodeAnalysis; +using System.Text.Json.Serialization.Metadata; using Elastic.Clients.Elasticsearch; +using Elastic.Clients.Elasticsearch.Serialization; using Elastic.Transport; using Elastic.Transport.Extensions; -using static System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes; - using Playground; -var settings = new ElasticsearchClientSettings(new Uri("https://primary.es.europe-west3.gcp.cloud.es.io")) +var pool = new SingleNodePool(new Uri("https://primary.es.europe-west3.gcp.cloud.es.io")); +var settings = new ElasticsearchClientSettings(pool, + sourceSerializer: (_, settings) => + new DefaultSourceSerializer(settings, PlaygroundJsonSerializerContext.Default) + ) .Authentication(new BasicAuthentication("elastic", "Oov35Wtxj5DzpZNzYAzFb0KZ")) .DisableDirectStreaming() .EnableDebugMode(cd => @@ -37,7 +41,7 @@ Console.WriteLine(id); Console.WriteLine(idByType); // This still errors on AOT compilation -//Console.WriteLine(client.SourceSerializer.SerializeToString(person)); +Console.WriteLine(client.SourceSerializer.SerializeToString(person)); [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = "Can only annotate our implementation")] [UnconditionalSuppressMessage("Trimming", "IL2067", Justification = "Can only annotate our implementation")]