diff --git a/.github/workflows/native-aot.yml b/.github/workflows/native-aot.yml index 1d81f4c1c..b0a78a58c 100644 --- a/.github/workflows/native-aot.yml +++ b/.github/workflows/native-aot.yml @@ -21,7 +21,7 @@ jobs: with: projectFile: src/examples/Documentation/Aot/NativeClient/NativeClient.csproj - # Packs Refit, Refit.HttpClientFactory and Refit.Testing once for the package consumer below. + # Packs Refit, Refit.Reflection, Refit.HttpClientFactory and Refit.Testing once for the package consumer below. pack-for-package-consumer: runs-on: ubuntu-latest env: @@ -46,7 +46,7 @@ jobs: shell: bash working-directory: src run: | - for project in Refit Refit.HttpClientFactory Refit.Testing; do + for project in Refit Refit.Reflection Refit.HttpClientFactory Refit.Testing; do dotnet pack "$project/$project.csproj" --configuration Release --output "$GITHUB_WORKSPACE/aot-feed" done diff --git a/CLAUDE.md b/CLAUDE.md index 17d68949a..d9d8c9b81 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -165,6 +165,7 @@ dotnet run --project "tests/Refit.GeneratorTests/Refit.GeneratorTests.csproj" -f - Shared target frameworks and package versions are centralized in `src/Directory.Build.props` and `src/Directory.Packages.props`. - The repository uses `LangVersion=latest`; use modern C# features where they improve clarity or generated-code quality. - AOT and trim analyzer behavior is enabled for compatible TFMs; prefer APIs that avoid reflection, dynamic code, and runtime type lookup. +- **No LINQ in production code.** Never use `System.Linq` (`Select`, `Where`, `OfType`, `FirstOrDefault`, `ToArray` and so on) in any shipping project, including the generator, analyzers and examples. Use plain loops. LINQ is allowed in test projects only. - Keep changes scoped. Do not rewrite unrelated files while touching generator/runtime paths. - Prefer focused tests that compile or execute the real generated output when changing source generator behavior. diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 2fa58a3c7..540946bfc 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -48,7 +48,7 @@ netstandard2.0 net462;net470;net471;net472;net48;net481 - net8.0;net9.0;net10.0;net11.0 + net10.0;net11.0 $(RefitFrameworkTargets);$(RefitModernTargets) $(RefitModernTargets) $(RefitModernTargets) diff --git a/src/InterfaceStubGenerator.Shared/BodyContentEmission.cs b/src/InterfaceStubGenerator.Shared/BodyContentEmission.cs index 4b4ca32f5..c7935d0f4 100644 --- a/src/InterfaceStubGenerator.Shared/BodyContentEmission.cs +++ b/src/InterfaceStubGenerator.Shared/BodyContentEmission.cs @@ -174,9 +174,9 @@ internal static string BuildInlineFormUnroll( } // CanUnrollForm rejects the null, HttpContent, Stream, string, and dictionary bodies the reflection path - // special-cases; a non-System.Text.Json serializer resolves field names differently, so it falls back too. + // special-cases; a serializer that does not report its name style resolves field names differently, so it falls back too. return $$""" - {{bodyIndent}}if ({{settingsLocal}}.ContentSerializer is global::Refit.SystemTextJsonContentSerializer + {{bodyIndent}}if ({{settingsLocal}}.ContentSerializer is global::Refit.IContentSerializerNameStyle {{inner}} && global::Refit.GeneratedRequestRunner.CanUnrollForm({{bodyExpr}})) {{bodyIndent}}{ {{inner}}var {{entriesLocal}} = new global::System.Collections.Generic.List<{{kvpType}}>({{fields.Length}}); @@ -206,8 +206,7 @@ internal static void AppendFormFieldUnroll( var propertyNameLiteral = Emitter.ToCSharpStringLiteral(field.PropertyName); var explicitNameLiteral = LiteralEmissionHelpers.ToNullableCSharpStringLiteral(field.ExplicitName); var prefixSegmentLiteral = LiteralEmissionHelpers.ToNullableCSharpStringLiteral(field.PrefixSegment); - var keyExpr = - $"global::Refit.GeneratedRequestRunner.BuildQueryKey({emission.SettingsLocal}, {propertyNameLiteral}, {explicitNameLiteral}, {prefixSegmentLiteral})"; + var keyExpr = BuildFormKeyExpression(field, emission.SettingsLocal, propertyNameLiteral, explicitNameLiteral, prefixSegmentLiteral); _ = sb.Append(indent).Append("var ").Append(valueLocal).Append(" = ").Append(site.BodyExpr).Append(".@").Append(field.PropertyName).AppendLine(";"); @@ -239,6 +238,31 @@ internal static void AppendFormFieldUnroll( _ = sb.Append(indent).AppendLine("}"); } + /// Builds the key expression for one unrolled form field, picking the serializer-aware helper when the field has serializer names. + /// The form field descriptor. + /// The settings local name. + /// The CLR property name literal. + /// The explicit name literal, or null. + /// The prefix segment literal, or null. + /// The key expression source. + internal static string BuildFormKeyExpression( + FormFieldModel field, + string settingsLocal, + string propertyNameLiteral, + string explicitNameLiteral, + string prefixSegmentLiteral) + { + if (field.JsonName is null && field.NewtonsoftName is null && field.XmlName is null) + { + return $"global::Refit.GeneratedRequestRunner.BuildQueryKey({settingsLocal}, {propertyNameLiteral}, {explicitNameLiteral}, {prefixSegmentLiteral})"; + } + + var json = LiteralEmissionHelpers.ToNullableCSharpStringLiteral(field.JsonName); + var newtonsoft = LiteralEmissionHelpers.ToNullableCSharpStringLiteral(field.NewtonsoftName); + var xml = LiteralEmissionHelpers.ToNullableCSharpStringLiteral(field.XmlName); + return $"global::Refit.GeneratedRequestRunner.BuildFormKey({settingsLocal}, {propertyNameLiteral}, {explicitNameLiteral}, {json}, {newtonsoft}, {xml}, {prefixSegmentLiteral})"; + } + /// Appends one entry-list Add using an explicit KeyValuePair construction (no C# 9 target-typed new). /// The statement builder. /// The shared locals and rendered fragments for the enclosing body. diff --git a/src/InterfaceStubGenerator.Shared/Emitter.cs b/src/InterfaceStubGenerator.Shared/Emitter.cs index 5ab4c4fbd..8ffbb1f3e 100644 --- a/src/InterfaceStubGenerator.Shared/Emitter.cs +++ b/src/InterfaceStubGenerator.Shared/Emitter.cs @@ -75,9 +75,11 @@ internal static class Emitter /// Emits the shared preserve attribute and factory registration code. /// The context generation model describing the interfaces. /// Callback used to add generated source files. + /// How the registration is hooked to assembly load in the consumer compilation. internal static void EmitSharedCode( ContextGenerationModel model, - Action addSource) + Action addSource, + ModuleInitializerSupport support = ModuleInitializerSupport.Guarded) { if (model.Interfaces.Length == 0) { @@ -86,7 +88,7 @@ internal static void EmitSharedCode( var generatedFileHeader = BuildSharedGeneratedFileHeader(model.Interfaces, model.EmitGeneratedCodeMarkers); SharedInfrastructureEmission.EmitPreserveAttribute(model, generatedFileHeader, addSource); - SharedInfrastructureEmission.EmitGeneratedFactoryModule(model, generatedFileHeader, addSource); + SharedInfrastructureEmission.EmitGeneratedFactoryModule(model, generatedFileHeader, addSource, support); } /// Emits the generated implementation source for a single interface. diff --git a/src/InterfaceStubGenerator.Shared/FormFieldEmission.cs b/src/InterfaceStubGenerator.Shared/FormFieldEmission.cs index 0c59d1904..1f1fdec07 100644 --- a/src/InterfaceStubGenerator.Shared/FormFieldEmission.cs +++ b/src/InterfaceStubGenerator.Shared/FormFieldEmission.cs @@ -7,6 +7,12 @@ namespace Refit.Generator; /// Emits the cached HTTP method field and form-field descriptor array for the inline path. internal static class FormFieldEmission { + /// The opening of the grouped compile-time field names argument. + private const string FormFieldNamesNew = "new global::Refit.FormFieldNames("; + + /// The closing of the grouped compile-time field names argument. + private const string FormFieldNamesClose = ")"; + /// Resolves the HTTP method expression, caching a custom verb in a static field. /// The parsed request model. /// The interface-scope unique name builder. @@ -117,8 +123,16 @@ internal static string BuildFormFieldElements( SpanBufferEmission.AppendText(destination, InlineRequestEmission.FormFieldNameOpen, ref position); SpanBufferEmission.AppendText(destination, field.PropertyName, ref position); SpanBufferEmission.AppendText(destination, InlineRequestEmission.FormFieldNameClose, ref position); + SpanBufferEmission.AppendText(destination, FormFieldNamesNew, ref position); SpanBufferEmission.AppendLiteralOrNull(destination, field.ExplicitName, ref position); SpanBufferEmission.AppendText(destination, InlineRequestEmission.ArgumentSeparator, ref position); + SpanBufferEmission.AppendLiteralOrNull(destination, field.JsonName, ref position); + SpanBufferEmission.AppendText(destination, InlineRequestEmission.ArgumentSeparator, ref position); + SpanBufferEmission.AppendLiteralOrNull(destination, field.NewtonsoftName, ref position); + SpanBufferEmission.AppendText(destination, InlineRequestEmission.ArgumentSeparator, ref position); + SpanBufferEmission.AppendLiteralOrNull(destination, field.XmlName, ref position); + SpanBufferEmission.AppendText(destination, FormFieldNamesClose, ref position); + SpanBufferEmission.AppendText(destination, InlineRequestEmission.ArgumentSeparator, ref position); SpanBufferEmission.AppendLiteralOrNull(destination, field.PrefixSegment, ref position); SpanBufferEmission.AppendText(destination, InlineRequestEmission.ArgumentSeparator, ref position); SpanBufferEmission.AppendLiteralOrNull(destination, field.Format, ref position); @@ -155,8 +169,16 @@ internal static int MeasureFormFieldElement(FormFieldModel field, string bodyTyp + InlineRequestEmission.FormFieldNameOpen.Length + field.PropertyName.Length + InlineRequestEmission.FormFieldNameClose.Length + + FormFieldNamesNew.Length + LiteralEmissionHelpers.LiteralOrNullLength(field.ExplicitName) + InlineRequestEmission.ArgumentSeparator.Length + + LiteralEmissionHelpers.LiteralOrNullLength(field.JsonName) + + InlineRequestEmission.ArgumentSeparator.Length + + LiteralEmissionHelpers.LiteralOrNullLength(field.NewtonsoftName) + + InlineRequestEmission.ArgumentSeparator.Length + + LiteralEmissionHelpers.LiteralOrNullLength(field.XmlName) + + FormFieldNamesClose.Length + + InlineRequestEmission.ArgumentSeparator.Length + LiteralEmissionHelpers.LiteralOrNullLength(field.PrefixSegment) + InlineRequestEmission.ArgumentSeparator.Length + LiteralEmissionHelpers.LiteralOrNullLength(field.Format) diff --git a/src/InterfaceStubGenerator.Shared/InlineRequestEmission.cs b/src/InterfaceStubGenerator.Shared/InlineRequestEmission.cs index c0fe6f512..13ca478e2 100644 --- a/src/InterfaceStubGenerator.Shared/InlineRequestEmission.cs +++ b/src/InterfaceStubGenerator.Shared/InlineRequestEmission.cs @@ -743,6 +743,22 @@ internal static string BuildRelativeUriExpression( return null; } + /// Determines whether the method's [Url] parameter accepts relative URI references. + /// The request model to inspect. + /// when a [Url] parameter exists and allows relative URIs. + internal static bool AllowsRelativeUrl(in RequestModel request) + { + foreach (var parameter in request.Bindings.Parameters) + { + if (parameter.Kind == RequestParameterKind.Url) + { + return parameter.AllowRelativeUrl; + } + } + + return false; + } + /// Builds the cancellation token expression for an inline generated method. /// The request model to inspect. /// The cancellation token expression. diff --git a/src/InterfaceStubGenerator.Shared/InterfaceMemberParsing.cs b/src/InterfaceStubGenerator.Shared/InterfaceMemberParsing.cs index f8bd6e7ff..9a3b22731 100644 --- a/src/InterfaceStubGenerator.Shared/InterfaceMemberParsing.cs +++ b/src/InterfaceStubGenerator.Shared/InterfaceMemberParsing.cs @@ -248,19 +248,43 @@ internal static MethodModel ParseNonRefitMethod( /// Name`1 corresponds to (Name, 1), so this classifies identically. internal static ReturnTypeInfo GetReturnTypeInfo(IMethodSymbol methodSymbol) => methodSymbol.ReturnType is INamedTypeSymbol named - ? (named.Name, named.Arity) switch + ? named.Arity switch { - ("Task", 0) => ReturnTypeInfo.AsyncVoid, - ("Task", 1) when InlineRequestClassification.IsHttpRequestMessageType(named.TypeArguments[0]) => ReturnTypeInfo.RequestMessage, - ("Task", 1) or ("ValueTask", 1) => ReturnTypeInfo.AsyncResult, - ("IAsyncEnumerable", 1) => ReturnTypeInfo.AsyncEnumerable, - ("IObservable", 1) => ReturnTypeInfo.Observable, - (PagedEnumerableName, PagedEnumerableArity) when RequestParameterParsingHelpers.IsInNamespace(named, "Refit") => ReturnTypeInfo.Paged, - ("Void", 0) => ReturnTypeInfo.SyncVoid, + 0 => ClassifyNonGenericReturn(named.Name), + 1 => ClassifySingleArgumentReturn(named), + PagedEnumerableArity => named.Name == PagedEnumerableName && RequestParameterParsingHelpers.IsInNamespace(named, "Refit") + ? ReturnTypeInfo.Paged + : ReturnTypeInfo.Return, _ => ReturnTypeInfo.Return } : ReturnTypeInfo.Return; + /// Classifies a return type that has no type arguments. + /// The type's name. + /// The classified return type information. + internal static ReturnTypeInfo ClassifyNonGenericReturn(string name) => + name switch + { + "Task" => ReturnTypeInfo.AsyncVoid, + "Void" => ReturnTypeInfo.SyncVoid, + _ => ReturnTypeInfo.Return + }; + + /// Classifies a return type that has one type argument. + /// The return type. + /// The classified return type information. + internal static ReturnTypeInfo ClassifySingleArgumentReturn(INamedTypeSymbol named) => + named.Name switch + { + "Task" => InlineRequestClassification.IsHttpRequestMessageType(named.TypeArguments[0]) + ? ReturnTypeInfo.RequestMessage + : ReturnTypeInfo.AsyncResult, + "ValueTask" => ReturnTypeInfo.AsyncResult, + "IAsyncEnumerable" => ReturnTypeInfo.AsyncEnumerable, + "IObservable" => ReturnTypeInfo.Observable, + _ => ReturnTypeInfo.Return + }; + /// Collects the distinct member names declared on the interface, preserving order. /// The directly declared members of the interface. /// The distinct member names. diff --git a/src/InterfaceStubGenerator.Shared/InterfaceSemanticParsing.cs b/src/InterfaceStubGenerator.Shared/InterfaceSemanticParsing.cs index ae9b9462c..c6cedd696 100644 --- a/src/InterfaceStubGenerator.Shared/InterfaceSemanticParsing.cs +++ b/src/InterfaceStubGenerator.Shared/InterfaceSemanticParsing.cs @@ -22,9 +22,10 @@ internal static InterfaceModel[] ParseMethodInterface( MethodDeclarationSyntax method, CancellationToken cancellationToken) { - var symbol = semanticModel.GetDeclaredSymbol(method, cancellationToken); + // A method declaration in the model's own syntax tree always has a declared symbol. + var symbol = semanticModel.GetDeclaredSymbol(method, cancellationToken)!; var attribute = semanticModel.Compilation.GetTypeByMetadataName("Refit.HttpMethodAttribute"); - if (symbol is null || attribute is null || !Parser.IsRefitMethod(symbol, attribute)) + if (attribute is null || !Parser.IsRefitMethod(symbol, attribute)) { return []; } @@ -289,9 +290,11 @@ private static InterfaceModel ParseInterface( } methods.Add(method); - if (!compilationNullableEnabled && method.DeclaringSyntaxReferences is { IsEmpty: false } references) + + // A method declared in source always has at least one declaring syntax reference. + if (!compilationNullableEnabled) { - nullableEnabled = IsNullableEnabled(references[0], semanticModel); + nullableEnabled = IsNullableEnabled(method.DeclaringSyntaxReferences[0], semanticModel); } } diff --git a/src/InterfaceStubGenerator.Shared/InterfaceStubGeneratorV2.cs b/src/InterfaceStubGenerator.Shared/InterfaceStubGeneratorV2.cs index 2b0ebafa7..c438ff487 100644 --- a/src/InterfaceStubGenerator.Shared/InterfaceStubGeneratorV2.cs +++ b/src/InterfaceStubGenerator.Shared/InterfaceStubGeneratorV2.cs @@ -6,6 +6,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; @@ -109,9 +110,28 @@ public void Initialize( .WithTrackingName(RefitGeneratorStepName.BuildRefit); context.EmitSource(interfaceModels); + var moduleInitializerSupport = context.CompilationProvider.Select(static (compilation, _) => + DetectModuleInitializerSupport(compilation)); + context.RegisterImplementationSourceOutput( - contextModel, - static (spc, model) => Emitter.EmitSharedCode(model, spc.AddSource)); + contextModel.Combine(moduleInitializerSupport), + static (spc, combined) => Emitter.EmitSharedCode(combined.Left, spc.AddSource, combined.Right)); + } + + /// Decides how the generated factory registration can be hooked to assembly load in a compilation. + /// The consumer compilation. + /// The module initializer support the compilation offers. + internal static ModuleInitializerSupport DetectModuleInitializerSupport(Compilation compilation) + { + // The compiler only recognises [ModuleInitializer] from C# 9. The generator only runs on C# compilations. + if (((CSharpCompilation)compilation).LanguageVersion < LanguageVersion.CSharp9) + { + return ModuleInitializerSupport.Guarded; + } + + return compilation.GetTypeByMetadataName("System.Runtime.CompilerServices.ModuleInitializerAttribute") is null + ? ModuleInitializerSupport.UnguardedWithPolyfill + : ModuleInitializerSupport.Unguarded; } /// Combines built-in and potential custom HTTP method candidates. diff --git a/src/InterfaceStubGenerator.Shared/MethodSignatureEmission.cs b/src/InterfaceStubGenerator.Shared/MethodSignatureEmission.cs index a78d6f43f..569353176 100644 --- a/src/InterfaceStubGenerator.Shared/MethodSignatureEmission.cs +++ b/src/InterfaceStubGenerator.Shared/MethodSignatureEmission.cs @@ -32,8 +32,7 @@ internal static InlineMethodFragments BuildInlineMethodFragments( // A [Url] method dispatches to an absolute URI (the validated [Url] value with any query appended), bypassing // the base-address merge; every other method builds a relative URI merged onto the base address. - var urlKind = InlineRequestEmission.FindRequestParameter(request, RequestParameterKind.Url) - ?.AllowRelativeUrl is true + var urlKind = InlineRequestEmission.AllowsRelativeUrl(request) ? "RelativeOrAbsolute" : "Absolute"; var requestUriExpression = InlineRequestEmission.HasUrlParameter(request) @@ -110,10 +109,7 @@ internal static void AppendInlineStandardRefitMethod( // A [Url] method dispatches to an absolute URI (the validated [Url] value with any query appended), bypassing // the base-address merge; every other method builds a relative URI merged onto the base address. - var urlKind = InlineRequestEmission.FindRequestParameter( - request, - RequestParameterKind.Url) - ?.AllowRelativeUrl is true + var urlKind = InlineRequestEmission.AllowsRelativeUrl(request) ? "RelativeOrAbsolute" : "Absolute"; var requestUriExpression = InlineRequestEmission.HasUrlParameter(request) diff --git a/src/InterfaceStubGenerator.Shared/Models/FormFieldModel.cs b/src/InterfaceStubGenerator.Shared/Models/FormFieldModel.cs index 8ee83a87f..edc8a6cd2 100644 --- a/src/InterfaceStubGenerator.Shared/Models/FormFieldModel.cs +++ b/src/InterfaceStubGenerator.Shared/Models/FormFieldModel.cs @@ -5,7 +5,7 @@ namespace Refit.Generator; /// Compile-time metadata for one form-url-encoded field of a strongly-typed body. /// The declared CLR property name read by the generated getter. -/// The explicit field name from [AliasAs] or [JsonPropertyName], or . +/// The explicit field name from [AliasAs] or [Query], which wins over every serializer name, or . /// The precomputed prefix + delimiter prepended to the field name, or . /// The [Query] value format, or . /// The explicit collection format underlying value, or to use the settings default. @@ -13,6 +13,9 @@ namespace Refit.Generator; /// Whether the field value can be and therefore needs a null guard. /// The reflection-free scalar value fast-path descriptor, or when the /// field is not a simple scalar (a collection or complex property) and the body must keep using the descriptor path. +/// The System.Text.Json [JsonPropertyName] name, or . +/// The Newtonsoft.Json [JsonProperty] name, or . +/// The [XmlElement] or [XmlAttribute] name, or . internal sealed record FormFieldModel( string PropertyName, string? ExplicitName, @@ -21,4 +24,7 @@ internal sealed record FormFieldModel( int? CollectionFormatValue, bool SerializeNull, bool CanBeNull, - InlineValueFormatModel? ValueFormat); + InlineValueFormatModel? ValueFormat, + string? JsonName, + string? NewtonsoftName, + string? XmlName); diff --git a/src/InterfaceStubGenerator.Shared/Models/FormPropertyAttributes.cs b/src/InterfaceStubGenerator.Shared/Models/FormPropertyAttributes.cs new file mode 100644 index 000000000..ad26eec80 --- /dev/null +++ b/src/InterfaceStubGenerator.Shared/Models/FormPropertyAttributes.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit.Generator; + +/// The naming and query attributes read from a form-body property. +/// The [AliasAs] name, or . +/// The [JsonPropertyName] name, or . +/// The Newtonsoft.Json [JsonProperty] name, or . +/// The [XmlElement] or [XmlAttribute] name, or . +/// The parsed [Query] data. +internal readonly record struct FormPropertyAttributes( + string? Alias, + string? Json, + string? Newtonsoft, + string? Xml, + RequestBodyParsing.QueryFormData Query); diff --git a/src/InterfaceStubGenerator.Shared/Models/ModuleInitializerSupport.cs b/src/InterfaceStubGenerator.Shared/Models/ModuleInitializerSupport.cs new file mode 100644 index 000000000..2dd765d99 --- /dev/null +++ b/src/InterfaceStubGenerator.Shared/Models/ModuleInitializerSupport.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit.Generator; + +/// Describes how the generated factory registration is hooked to assembly load in the consumer compilation. +internal enum ModuleInitializerSupport +{ + /// The registration is emitted only for targets that define NET5_0_OR_GREATER, because the language or the target cannot run a module initializer. + Guarded = 0, + + /// The registration is always emitted, because the compilation already defines ModuleInitializerAttribute. + Unguarded = 1, + + /// The registration is always emitted and the generator declares ModuleInitializerAttribute for targets that lack it. + UnguardedWithPolyfill = 2, +} diff --git a/src/InterfaceStubGenerator.Shared/ParameterMetadataEmission.cs b/src/InterfaceStubGenerator.Shared/ParameterMetadataEmission.cs index 0abf8ac87..a1890793a 100644 --- a/src/InterfaceStubGenerator.Shared/ParameterMetadataEmission.cs +++ b/src/InterfaceStubGenerator.Shared/ParameterMetadataEmission.cs @@ -86,7 +86,7 @@ internal static void BuildParameterInfoField( var memberIndent = SpanBufferEmission.Indent(Emitter.MethodMemberIndentation); _ = sb.AppendLine().Append(memberIndent).Append("/// Cached attribute provider for the generated ") .Append(Emitter.ToXmlDocumentationText(method)).Append(" method's ").Append(Emitter.ToXmlDocumentationText(parameter.Identity.Name)).AppendLine(" parameter.") - .Append(memberIndent).Append("private static readonly global::System.Reflection.ICustomAttributeProvider ").Append(paramInfoFieldName).Append(" = "); + .Append(memberIndent).Append("private static readonly global::Refit.IParameterAttributeProvider ").Append(paramInfoFieldName).Append(" = "); // A parameter with no attributes shares the singleton empty provider instead of allocating an empty dictionary. if (parameter.Attributes.Length == 0) diff --git a/src/InterfaceStubGenerator.Shared/QueryDictionaryEmission.cs b/src/InterfaceStubGenerator.Shared/QueryDictionaryEmission.cs index 5d92b6ea6..8d6b22cb3 100644 --- a/src/InterfaceStubGenerator.Shared/QueryDictionaryEmission.cs +++ b/src/InterfaceStubGenerator.Shared/QueryDictionaryEmission.cs @@ -92,7 +92,7 @@ internal static void AppendDictionaryEntryStatements( var dictionary = query.Dictionary!; var (entryLocal, keyLocal, valueLocal, indent) = entry; var keyTypeOf = $"typeof({dictionary.KeyTypeName})"; - var customKey = QueryObjectEmission.EmitFormatUrlParameter($"{entryLocal}.Key", keyTypeOf, keyTypeOf, emission); + var customKey = QueryObjectEmission.EmitFormatUrlParameter($"{entryLocal}.Key", QueryObjectEmission.EmptyProviderExpression, keyTypeOf, emission); var fastKey = QueryValueEmission.BuildFastFormatExpression($"{entryLocal}.Key", dictionary.KeyFormat, emission); var keyExpression = fastKey is null ? customKey diff --git a/src/InterfaceStubGenerator.Shared/QueryObjectEmission.cs b/src/InterfaceStubGenerator.Shared/QueryObjectEmission.cs index d6fea1e37..6619c0c36 100644 --- a/src/InterfaceStubGenerator.Shared/QueryObjectEmission.cs +++ b/src/InterfaceStubGenerator.Shared/QueryObjectEmission.cs @@ -10,6 +10,9 @@ namespace Refit.Generator; /// Flattens a complex query object's properties into query-string statements. internal static class QueryObjectEmission { + /// The expression for the shared attribute provider of values that declare no attributes, such as dictionary keys and collection elements. + internal const string EmptyProviderExpression = "global::Refit.GeneratedParameterAttributeProvider.Empty"; + /// Appends the statements flattening one query object's properties into query pairs. /// The statement builder. /// The parameter model. @@ -231,7 +234,7 @@ internal static (string EntryKeyExpression, string ValueExpression) BuildDiction in QueryParameterEmission.InlineValueEmission emission) { var keyTypeOf = $"typeof({dictionary.KeyTypeName})"; - var customKey = EmitFormatUrlParameter($"{entryLocal}.Key", keyTypeOf, keyTypeOf, emission); + var customKey = EmitFormatUrlParameter($"{entryLocal}.Key", EmptyProviderExpression, keyTypeOf, emission); var fastKey = QueryValueEmission.BuildFastFormatExpression($"{entryLocal}.Key", dictionary.KeyFormat, emission); var entryKeyExpression = fastKey is null ? customKey @@ -475,7 +478,7 @@ internal static string BuildFastCollectionElementExpression( // An element with no reflection-free rendering (e.g. an enum with duplicate constants) still uses the // formatter, which under the pristine default renders it correctly; the type doubles as the provider. var elementTypeOf = $"typeof({collection.PropertyTypeName})"; - return EmitFormatUrlParameter(elementLocal, elementTypeOf, elementTypeOf, emission); + return EmitFormatUrlParameter(elementLocal, EmptyProviderExpression, elementTypeOf, emission); } // A string element renders itself, so a null element already renders as null; other formats guard first. diff --git a/src/InterfaceStubGenerator.Shared/QueryParameterParsing.cs b/src/InterfaceStubGenerator.Shared/QueryParameterParsing.cs index e2f9ce0e2..625e74877 100644 --- a/src/InterfaceStubGenerator.Shared/QueryParameterParsing.cs +++ b/src/InterfaceStubGenerator.Shared/QueryParameterParsing.cs @@ -361,9 +361,15 @@ internal static bool TryBuildQueryModel( elementProperties, null, null, - data.Delimiter ?? DefaultNestingDelimiter); + ResolveNestingDelimiter(data)); } + /// Gets the delimiter the parameter declares, or the default nesting delimiter. + /// The parameter's parsed [Query] data. + /// The delimiter to place between nested keys. + internal static string ResolveNestingDelimiter(in RequestBodyParsing.QueryFormData data) => + data.Delimiter ?? DefaultNestingDelimiter; + /// Builds the query model for a [QueryConverter] parameter, or null when the type is unresolved. /// The parameter carrying the converter. /// The [QueryConverter] attribute. diff --git a/src/InterfaceStubGenerator.Shared/RequestBodyParsing.cs b/src/InterfaceStubGenerator.Shared/RequestBodyParsing.cs index 76b25c60c..ee6cc2586 100644 --- a/src/InterfaceStubGenerator.Shared/RequestBodyParsing.cs +++ b/src/InterfaceStubGenerator.Shared/RequestBodyParsing.cs @@ -119,26 +119,8 @@ internal static FormFieldModel BuildFormFieldModel( IPropertySymbol property, in InterfaceGenerationContext context) { - string? aliasName = null; - string? jsonName = null; - var query = default(QueryFormData); - - foreach (var attribute in property.GetAttributes()) - { - var attributeName = attribute.AttributeClass!.ToDisplayString(); - if (attributeName == "Refit.AliasAsAttribute") - { - aliasName = GetFirstStringArgument(attribute); - } - else if (attributeName == "System.Text.Json.Serialization.JsonPropertyNameAttribute") - { - jsonName = GetFirstStringArgument(attribute); - } - else if (attributeName == "Refit.QueryAttribute") - { - query = ParseFormQueryAttribute(attribute); - } - } + var attributes = ReadFormPropertyAttributes(property); + var query = attributes.Query; // A scalar property (string/bool/IFormattable, matching the query fast path) can be rendered straight-line // without the descriptor array; collections and complex properties leave ValueFormat null so the whole body @@ -156,13 +138,101 @@ internal static FormFieldModel BuildFormFieldModel( var prefixSegment = string.IsNullOrWhiteSpace(query.Prefix) ? null : query.Prefix + query.Delimiter; return new( property.Name, - aliasName ?? query.Name ?? jsonName, + attributes.Alias ?? query.Name, prefixSegment, query.Format, query.CollectionFormatValue, query.SerializeNull, QueryParameterParsing.CanElementBeNull(property.Type), - valueFormat); + valueFormat, + attributes.Json, + attributes.Newtonsoft, + attributes.Xml); + } + + /// Reads the form-relevant naming and query attributes from a body property. + /// The property to inspect. + /// The alias, serializer-specific names and query data. + internal static FormPropertyAttributes ReadFormPropertyAttributes(IPropertySymbol property) + { + string? alias = null; + string? json = null; + string? newtonsoft = null; + string? xmlElement = null; + string? xmlAttribute = null; + var query = default(QueryFormData); + + foreach (var attribute in property.GetAttributes()) + { + switch (attribute.AttributeClass!.ToDisplayString()) + { + case "Refit.AliasAsAttribute": + { + alias = GetFirstStringArgument(attribute); + break; + } + + case "System.Text.Json.Serialization.JsonPropertyNameAttribute": + { + json = GetFirstStringArgument(attribute); + break; + } + + case "Newtonsoft.Json.JsonPropertyAttribute": + { + newtonsoft = ReadAttributeName(attribute, "PropertyName", null); + break; + } + + case "System.Xml.Serialization.XmlElementAttribute": + { + // An unnamed [XmlElement] reports an empty ElementName, which the reflection path returns as the name. + xmlElement = ReadAttributeName(attribute, "ElementName", string.Empty); + break; + } + + case "System.Xml.Serialization.XmlAttributeAttribute": + { + xmlAttribute = ReadAttributeName(attribute, "AttributeName", string.Empty); + break; + } + + case "Refit.QueryAttribute": + { + query = ParseFormQueryAttribute(attribute); + break; + } + } + } + + return new(alias, json, newtonsoft, xmlElement ?? xmlAttribute, query); + } + + /// Reads an attribute's name from its first string argument or a named argument. + /// The attribute to inspect. + /// The named argument that can carry the name. + /// The value to return when the attribute carries no name. + /// The attribute's name, or . + internal static string? ReadAttributeName(AttributeData attribute, string namedArgument, string? whenMissing) => + GetFirstStringArgument(attribute) ?? GetNamedStringArgument(attribute, namedArgument) ?? whenMissing; + + /// Reads a named string argument from an attribute. + /// The attribute to inspect. + /// The named argument to read. + /// The string value, or when the argument is absent. + internal static string? GetNamedStringArgument( + AttributeData attribute, + string name) + { + foreach (var argument in attribute.NamedArguments) + { + if (argument.Key == name && argument.Value.Value is string value) + { + return value; + } + } + + return null; } /// Reads the first string constructor argument from an attribute. diff --git a/src/InterfaceStubGenerator.Shared/RequestParameterKindParsing.cs b/src/InterfaceStubGenerator.Shared/RequestParameterKindParsing.cs index 0243d1d00..e37b07a19 100644 --- a/src/InterfaceStubGenerator.Shared/RequestParameterKindParsing.cs +++ b/src/InterfaceStubGenerator.Shared/RequestParameterKindParsing.cs @@ -448,10 +448,8 @@ internal static bool TryParseUrlParameter( var allowRelative = false; foreach (var argument in attribute.NamedArguments) { - if (argument.Key == "AllowRelative" && argument.Value.Value is true) - { - allowRelative = true; - } + // AllowRelative is the attribute's only settable member. + allowRelative |= Equals(argument.Value.Value, true); } urlParameter = new( diff --git a/src/InterfaceStubGenerator.Shared/SharedInfrastructureEmission.cs b/src/InterfaceStubGenerator.Shared/SharedInfrastructureEmission.cs index 28a791b52..4a792216a 100644 --- a/src/InterfaceStubGenerator.Shared/SharedInfrastructureEmission.cs +++ b/src/InterfaceStubGenerator.Shared/SharedInfrastructureEmission.cs @@ -54,11 +54,17 @@ internal sealed class PreserveAttribute : global::System.Attribute /// The context generation model describing the interfaces. /// The shared generated file header. /// Callback used to add generated source files. + /// How the registration is hooked to assembly load in the consumer compilation. internal static void EmitGeneratedFactoryModule( ContextGenerationModel model, string generatedFileHeader, - Action addSource) + Action addSource, + ModuleInitializerSupport support = ModuleInitializerSupport.Guarded) { + // A compiler lowers [ModuleInitializer] into the module constructor on every target, so a target that lacks the + // attribute only needs it declared. Without it, .NET Framework clients would never register. + var guardStart = support == ModuleInitializerSupport.Guarded ? "#if NET5_0_OR_GREATER" : string.Empty; + var guardEnd = support == ModuleInitializerSupport.Guarded ? "#endif" : string.Empty; var generatedSource = $$""" {{generatedFileHeader}} namespace Refit.Implementation @@ -72,24 +78,53 @@ namespace Refit.Implementation [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] internal static partial class {{model.GeneratedClassName}} { - #if NET5_0_OR_GREATER + {{guardStart}} /// Registers generated Refit factories when the assembly is loaded. [global::System.Diagnostics.CodeAnalysis.SuppressMessage( "Usage", "CA2255:The ModuleInitializer attribute should not be used in libraries", Justification = "ModuleInitializer is used intentionally so generated Refit factories are registered when the assembly loads.")] [System.Runtime.CompilerServices.ModuleInitializer] - [System.Diagnostics.CodeAnalysis.DynamicDependency( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, - typeof(global::Refit.Implementation.{{model.GeneratedClassName}}))] internal static void Initialize() { {{Emitter.BuildGeneratedFactoryRegistrations(model.Interfaces)}} } - #endif + {{guardEnd}} } } """; addSource("Generated.g.cs", Emitter.ToSourceText(generatedSource)); + + if (support == ModuleInitializerSupport.UnguardedWithPolyfill) + { + EmitModuleInitializerPolyfill(generatedFileHeader, addSource); + } + } + + /// Declares ModuleInitializerAttribute for targets whose framework does not define it. + /// The shared generated file header. + /// Callback used to add generated source files. + internal static void EmitModuleInitializerPolyfill( + string generatedFileHeader, + Action addSource) + { + var polyfillSource = $$""" + {{generatedFileHeader}} + #if !NET5_0_OR_GREATER + namespace System.Runtime.CompilerServices + { + /// Marks a method the compiler runs when the module loads. + {{Emitter.GeneratedCodeAttribute}} + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + [global::System.AttributeUsage(global::System.AttributeTargets.Method, Inherited = false)] + internal sealed class ModuleInitializerAttribute : global::System.Attribute + { + } + } + #endif + + """; + addSource("ModuleInitializerAttribute.g.cs", Emitter.ToSourceText(polyfillSource)); } } diff --git a/src/Polyfills/DynamicDependencyAttribute.cs b/src/Polyfills/DynamicDependencyAttribute.cs deleted file mode 100644 index db368a3e6..000000000 --- a/src/Polyfills/DynamicDependencyAttribute.cs +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. -// ReactiveUI and Contributors licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -#if !NET5_0_OR_GREATER -namespace System.Diagnostics.CodeAnalysis; - -/// Polyfill of the DynamicDependency attribute for older target frameworks. -[ExcludeFromCodeCoverage] -[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method, AllowMultiple = true)] -internal sealed class DynamicDependencyAttribute : Attribute, DynamicDependencyAttribute.IMetadata -{ - /// Initializes a new instance of the class. - /// The member types to preserve. - /// The owning type. - internal DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, Type type) - { - MemberTypes = memberTypes; - Type = type; - } - - /// Initializes a new instance of the class. - /// The signature of the depended-upon member. - /// The owning type. - internal DynamicDependencyAttribute(string memberSignature, Type type) - { - MemberSignature = memberSignature; - Type = type; - } - - /// Defines the trimming-required public metadata contract. - internal interface IMetadata - { - /// Gets the member categories that form the dependency. - DynamicallyAccessedMemberTypes MemberTypes { get; } - - /// Gets the type that owns the dependency. - Type? Type { get; } - - /// Gets the dependent member signature. - string? MemberSignature { get; } - } - - /// Gets the member types that must be preserved. - public DynamicallyAccessedMemberTypes MemberTypes { get; } - - /// Gets the type that owns the depended-upon members. - public Type? Type { get; } - - /// Gets the signature of the depended-upon member. - public string? MemberSignature { get; } -} -#endif diff --git a/src/Refit.Analyzers.Roslyn48/Refit.Analyzers.Roslyn48.csproj b/src/Refit.Analyzers.Roslyn48/Refit.Analyzers.Roslyn48.csproj index 5df1f8675..983636614 100644 --- a/src/Refit.Analyzers.Roslyn48/Refit.Analyzers.Roslyn48.csproj +++ b/src/Refit.Analyzers.Roslyn48/Refit.Analyzers.Roslyn48.csproj @@ -47,6 +47,7 @@ + diff --git a/src/Refit.Analyzers.Shared/FallbackExplanation.cs b/src/Refit.Analyzers.Shared/FallbackExplanation.cs index 66a33b982..e81688caa 100644 --- a/src/Refit.Analyzers.Shared/FallbackExplanation.cs +++ b/src/Refit.Analyzers.Shared/FallbackExplanation.cs @@ -221,15 +221,10 @@ internal static Explanation Describe(IMethodSymbol method, in InlineFallback fal /// The return type's location, or when the method has no source declaration. private static Location? GetReturnTypeLocation(IMethodSymbol method) { - foreach (var reference in method.DeclaringSyntaxReferences) - { - if (reference.GetSyntax() is MethodDeclarationSyntax declaration) - { - return declaration.ReturnType.GetLocation(); - } - } - - return null; + var references = method.DeclaringSyntaxReferences; + return !references.IsEmpty && references[0].GetSyntax() is MethodDeclarationSyntax declaration + ? declaration.ReturnType.GetLocation() + : null; } /// Formats a type the way a user wrote it. diff --git a/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionCore.cs b/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionCore.cs new file mode 100644 index 000000000..a8fe7da59 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionCore.cs @@ -0,0 +1,271 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. +using System.Diagnostics.CodeAnalysis; +using System.Reflection; +using Microsoft.Extensions.DependencyInjection; + +namespace Refit; + +/// Registration logic backing the reflection-based Refit HttpClientFactory extension methods. +internal static class HttpClientFactoryReflectionCore +{ + /// Lazily cached generic RequestBuilder.ForType method used to build request builders by type. + private static MethodInfo? _requestBuilderGenericForTypeMethod; + + /// Registers a Refit client and its dependencies for the given interface type. + /// The service collection to register into. + /// The Refit interface type to register. + /// A factory that produces the Refit settings, or null. + /// A name for the underlying HTTP client, or null. + /// The HTTP client builder for further configuration. + internal static IHttpClientBuilder AddRefitClientCore( + IServiceCollection services, + Type refitInterfaceType, + Func? settings, + string? httpClientName) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + // register settings + var settingsType = typeof(SettingsFor<>).MakeGenericType(refitInterfaceType); + _ = services.AddSingleton( + settingsType, + provider => Activator.CreateInstance( + typeof(SettingsFor<>).MakeGenericType(refitInterfaceType), + settings?.Invoke(provider))!); + + // register RequestBuilder + var requestBuilderType = typeof(IRequestBuilder<>).MakeGenericType(refitInterfaceType); + _ = services.AddSingleton( + requestBuilderType, + provider => GetRequestBuilderGenericForTypeMethod() + .MakeGenericMethod(refitInterfaceType) + .Invoke( + null, + [((ISettingsFor)provider.GetRequiredService(settingsType)).Settings])!); + + // create HttpClientBuilder + var builder = services.AddHttpClient(httpClientName ?? UniqueName.ForType(refitInterfaceType)); + + // configure the primary handler from the supplied settings (or fall back to the default) + _ = builder.ConfigurePrimaryHttpMessageHandler(serviceProvider => + HttpClientFactoryCore.CreateInnerHandlerIfProvided( + ((ISettingsFor)serviceProvider.GetRequiredService(settingsType)).Settings) + ?? new HttpClientHandler()); + + // add typed client (register transient that resolves HttpClient from IHttpClientFactory and creates Refit client) + _ = builder.Services.AddTransient( + refitInterfaceType, + s => + { + var httpClientFactory = s.GetRequiredService(); + var httpClient = httpClientFactory.CreateClient(builder.Name); + return RestService.For( + refitInterfaceType, + httpClient, + (IRequestBuilder)s.GetRequiredService(requestBuilderType)); + }); + + return builder; + } + + /// Registers a strongly typed Refit client and its dependencies. + /// The Refit interface type to register. + /// The service collection to register into. + /// A factory that produces the Refit settings, or null. + /// A name for the underlying HTTP client, or null. + /// The HTTP client builder for further configuration. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + internal static IHttpClientBuilder AddRefitClientCore< + T>( + IServiceCollection services, + Func? settings, + string? httpClientName) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + // register settings + _ = services.AddSingleton(provider => new SettingsFor(settings?.Invoke(provider))); + + // register RequestBuilder + _ = services.AddSingleton(static provider => + RequestBuilder.ForType(provider.GetRequiredService>().Settings)); + + // create HttpClientBuilder + var builder = services.AddHttpClient(httpClientName ?? UniqueName.ForType()); + + // configure the primary handler from the supplied settings (or fall back to the default) + _ = builder.ConfigurePrimaryHttpMessageHandler(static serviceProvider => + HttpClientFactoryCore.CreateInnerHandlerIfProvided( + serviceProvider.GetRequiredService>().Settings) + ?? new HttpClientHandler()); + + // add typed client using framework AddTypedClient + return builder.AddTypedClient(static (client, serviceProvider) => + RestService.For( + client, + serviceProvider.GetRequiredService>())); + } + + /// Registers a keyed Refit client and its dependencies for the given interface type. + /// The service collection to register into. + /// The Refit interface type to register. + /// The key under which the client is registered. + /// A factory that produces the Refit settings, or null. + /// A name for the underlying HTTP client, or null. + /// The HTTP client builder for further configuration. + internal static IHttpClientBuilder AddKeyedRefitClientCore( + IServiceCollection services, + Type refitInterfaceType, + object? serviceKey, + Func? settings, + string? httpClientName) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + // register settings + var settingsType = typeof(SettingsFor<>).MakeGenericType(refitInterfaceType); + _ = services.AddKeyedSingleton( + settingsType, + serviceKey, + (provider, _) => Activator.CreateInstance( + typeof(SettingsFor<>).MakeGenericType(refitInterfaceType), + settings?.Invoke(provider))!); + + // register RequestBuilder + var requestBuilderType = typeof(IRequestBuilder<>).MakeGenericType(refitInterfaceType); + _ = services.AddKeyedSingleton( + requestBuilderType, + serviceKey, + (provider, _) => GetRequestBuilderGenericForTypeMethod() + .MakeGenericMethod(refitInterfaceType) + .Invoke( + null, + [((ISettingsFor)provider.GetRequiredKeyedService(settingsType, serviceKey)).Settings])!); + + // create HttpClientBuilder + var builder = services.AddHttpClient(httpClientName ?? UniqueName.ForType(refitInterfaceType, serviceKey)); + + // configure primary and additional handlers from the keyed settings + HttpClientFactoryCore.ConfigureKeyedHandlers( + builder, + serviceProvider => (ISettingsFor)serviceProvider.GetRequiredKeyedService(settingsType, serviceKey)); + + // add keyed typed client (register keyed transient that resolves HttpClient and creates Refit client) + _ = builder.Services.AddKeyedTransient( + refitInterfaceType, + serviceKey, + (s, _) => + { + var httpClientFactory = s.GetRequiredService(); + var httpClient = httpClientFactory.CreateClient(builder.Name); + return RestService.For( + refitInterfaceType, + httpClient, + (IRequestBuilder)s.GetRequiredKeyedService(requestBuilderType, serviceKey)); + }); + + return builder; + } + + /// Registers a strongly typed keyed Refit client and its dependencies. + /// The Refit interface type to register. + /// The service collection to register into. + /// The key under which the client is registered. + /// A factory that produces the Refit settings, or null. + /// A name for the underlying HTTP client, or null. + /// The HTTP client builder for further configuration. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + internal static IHttpClientBuilder AddKeyedRefitClientCore< + T>( + IServiceCollection services, + object? serviceKey, + Func? settings, + string? httpClientName) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + // register settings + _ = services.AddKeyedSingleton( + serviceKey, + (provider, _) => new SettingsFor(settings?.Invoke(provider))); + + // register RequestBuilder + _ = services.AddKeyedSingleton( + serviceKey, + (provider, _) => + RequestBuilder.ForType( + provider.GetRequiredKeyedService>(serviceKey).Settings)); + + // create HttpClientBuilder + var builder = services.AddHttpClient(httpClientName ?? UniqueName.ForType(serviceKey)); + + // configure primary and additional handlers from the keyed settings + HttpClientFactoryCore.ConfigureKeyedHandlers( + builder, + serviceProvider => serviceProvider.GetRequiredKeyedService>(serviceKey)); + + // add keyed typed client (inline keyed registration) + _ = builder.Services.AddKeyedTransient( + serviceKey, + (s, _) => + { + var httpClientFactory = s.GetRequiredService(); + var httpClient = httpClientFactory.CreateClient(builder.Name); + return RestService.For( + httpClient, + s.GetRequiredKeyedService>(serviceKey)); + }); + + return builder; + } + + /// Resolves and caches the open generic method. + /// The open generic RequestBuilder.ForType method definition. + private static MethodInfo GetRequestBuilderGenericForTypeMethod() => + _requestBuilderGenericForTypeMethod ??= FindRequestBuilderGenericForTypeMethod(); + + /// Finds the open generic method. + /// The matching method definition. + /// declares no single-parameter generic ForType method, or more than one. + [ExcludeFromCodeCoverage] // RequestBuilder declares exactly one single-parameter generic ForType, so the duplicate-match and no-match guards are unreachable. + private static MethodInfo FindRequestBuilderGenericForTypeMethod() + { + var methods = typeof(RequestBuilder).GetMethods(BindingFlags.Public | BindingFlags.Static); + MethodInfo? match = null; + for (var i = 0; i < methods.Length; i++) + { + var method = methods[i]; + if (!method.IsGenericMethodDefinition || method.GetParameters().Length != 1) + { + continue; + } + + if (match is not null) + { + throw new InvalidOperationException("Sequence contains more than one matching element"); + } + + match = method; + } + + return match ?? throw new InvalidOperationException("Sequence contains no matching element"); + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionExtensions.HttpClientBuilder.cs b/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionExtensions.HttpClientBuilder.cs new file mode 100644 index 000000000..45dee7d37 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionExtensions.HttpClientBuilder.cs @@ -0,0 +1,278 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. +using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.DependencyInjection; + +namespace Refit; + +/// Extension methods for registering reflection-based Refit clients with dependency injection. +public static partial class HttpClientFactoryReflectionExtensions +{ + /// Registers Refit clients on an existing . + /// The HTTP client builder the Refit client is registered with. + extension(IHttpClientBuilder builder) + { + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddRefitClient(Type refitInterfaceType) + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + builder.Services, + refitInterfaceType, + static _ => null, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The settings used to configure the instance. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddRefitClient( + Type refitInterfaceType, + RefitSettings? settings) + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + builder.Services, + refitInterfaceType, + _ => settings, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// An action used to configure the Refit settings from the service provider. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public IHttpClientBuilder AddRefitClient( + Type refitInterfaceType, + Func? settingsAction) + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + builder.Services, + refitInterfaceType, + settingsAction, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddRefitClient< + T>() + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + builder.Services, + static _ => null, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The settings used to configure the instance. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddRefitClient< + T>(RefitSettings? settings) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + builder.Services, + _ => settings, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// An action used to configure the Refit settings from the service provider. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddRefitClient< + T>(Func? settingsAction) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + builder.Services, + settingsAction, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddKeyedRefitClient( + Type refitInterfaceType, + object? serviceKey) + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + builder.Services, + refitInterfaceType, + serviceKey, + static _ => null, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The settings used to configure the instance. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddKeyedRefitClient( + Type refitInterfaceType, + object? serviceKey, + RefitSettings? settings) + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + builder.Services, + refitInterfaceType, + serviceKey, + _ => settings, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// An action used to configure the Refit settings from the service provider. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public IHttpClientBuilder AddKeyedRefitClient( + Type refitInterfaceType, + object? serviceKey, + Func? settingsAction) + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + builder.Services, + refitInterfaceType, + serviceKey, + settingsAction, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddKeyedRefitClient< + T>(object? serviceKey) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + builder.Services, + serviceKey, + static _ => null, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The settings used to configure the instance. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddKeyedRefitClient< + T>( + object? serviceKey, + RefitSettings? settings) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + builder.Services, + serviceKey, + _ => settings, + builder.Name); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// An action used to configure the Refit settings from the service provider. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddKeyedRefitClient< + T>( + object? serviceKey, + Func? settingsAction) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(builder); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + builder.Services, + serviceKey, + settingsAction, + builder.Name); + } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionExtensions.ServiceCollection.cs b/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionExtensions.ServiceCollection.cs new file mode 100644 index 000000000..b3aedd16f --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/HttpClientFactoryReflectionExtensions.ServiceCollection.cs @@ -0,0 +1,478 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. +using System.Diagnostics.CodeAnalysis; +using Microsoft.Extensions.DependencyInjection; + +namespace Refit; + +/// Extension methods for registering reflection-based Refit clients with dependency injection. +public static partial class HttpClientFactoryReflectionExtensions +{ + /// Registers Refit clients directly on an . + /// The service collection the Refit client is registered with. + extension(IServiceCollection services) + { + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddRefitClient(Type refitInterfaceType) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + refitInterfaceType, + static _ => null, + null); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The settings used to configure the instance. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddRefitClient( + Type refitInterfaceType, + RefitSettings? settings) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + refitInterfaceType, + _ => settings, + null); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The settings used to configure the instance. + /// Allows the name of the underlying HttpClient to be changed. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddRefitClient( + Type refitInterfaceType, + RefitSettings? settings, + string? httpClientName) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + refitInterfaceType, + _ => settings, + httpClientName); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// An action used to configure the Refit settings from the service provider. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public IHttpClientBuilder AddRefitClient( + Type refitInterfaceType, + Func? settingsAction) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + refitInterfaceType, + settingsAction, + null); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// An action used to configure the Refit settings from the service provider. + /// Allows the name of the underlying HttpClient to be changed. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public IHttpClientBuilder AddRefitClient( + Type refitInterfaceType, + Func? settingsAction, + string? httpClientName) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + refitInterfaceType, + settingsAction, + httpClientName); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddRefitClient< + T>() + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + static _ => null, + null); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The settings used to configure the instance. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddRefitClient< + T>(RefitSettings? settings) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + _ => settings, + null); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// The settings used to configure the instance. + /// Allows the name of the underlying HttpClient to be changed. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddRefitClient< + T>( + RefitSettings? settings, + string? httpClientName) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + _ => settings, + httpClientName); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// An action used to configure the Refit settings from the service provider. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddRefitClient< + T>(Func? settingsAction) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + settingsAction, + null); + } + + /// Adds a Refit client to the dependency injection container. + /// The type of the Refit interface. + /// An action used to configure the Refit settings from the service provider. + /// Allows the name of the underlying HttpClient to be changed. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddRefitClient< + T>( + Func? settingsAction, + string? httpClientName) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + return HttpClientFactoryReflectionCore.AddRefitClientCore( + services, + settingsAction, + httpClientName); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddKeyedRefitClient( + Type refitInterfaceType, + object? serviceKey) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + refitInterfaceType, + serviceKey, + static _ => null, + null); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The settings used to configure the instance. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddKeyedRefitClient( + Type refitInterfaceType, + object? serviceKey, + RefitSettings? settings) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + refitInterfaceType, + serviceKey, + _ => settings, + null); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The settings used to configure the instance. + /// Allows the name of the underlying HttpClient to be changed. + /// The HTTP client builder for chaining. + public IHttpClientBuilder AddKeyedRefitClient( + Type refitInterfaceType, + object? serviceKey, + RefitSettings? settings, + string? httpClientName) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + refitInterfaceType, + serviceKey, + _ => settings, + httpClientName); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// An action used to configure the Refit settings from the service provider. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public IHttpClientBuilder AddKeyedRefitClient( + Type refitInterfaceType, + object? serviceKey, + Func? settingsAction) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + refitInterfaceType, + serviceKey, + settingsAction, + null); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// An action used to configure the Refit settings from the service provider. + /// Allows the name of the underlying HttpClient to be changed. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public IHttpClientBuilder AddKeyedRefitClient( + Type refitInterfaceType, + object? serviceKey, + Func? settingsAction, + string? httpClientName) + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + refitInterfaceType, + serviceKey, + settingsAction, + httpClientName); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddKeyedRefitClient< + T>(object? serviceKey) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + serviceKey, + static _ => null, + null); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The settings used to configure the instance. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddKeyedRefitClient< + T>( + object? serviceKey, + RefitSettings? settings) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + serviceKey, + _ => settings, + null); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// The settings used to configure the instance. + /// Allows the name of the underlying HttpClient to be changed. + /// The HTTP client builder for chaining. + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddKeyedRefitClient< + T>( + object? serviceKey, + RefitSettings? settings, + string? httpClientName) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + serviceKey, + _ => settings, + httpClientName); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// An action used to configure the Refit settings from the service provider. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddKeyedRefitClient< + T>( + object? serviceKey, + Func? settingsAction) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + serviceKey, + settingsAction, + null); + } + + /// Adds a Refit client to the dependency injection container with a specified service key. + /// The type of the Refit interface. + /// A key used to associate with the specific Refit client instance. + /// An action used to configure the Refit settings from the service provider. + /// Allows the name of the underlying HttpClient to be changed. + /// The HTTP client builder for chaining. + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "The Refit interface type is intentionally specified explicitly by callers.")] + public IHttpClientBuilder AddKeyedRefitClient< + T>( + object? serviceKey, + Func? settingsAction, + string? httpClientName) + where T : class + { + ArgumentExceptionHelper.ThrowIfNull(services); + + ArgumentExceptionHelper.ThrowIfNull(serviceKey); + + return HttpClientFactoryReflectionCore.AddKeyedRefitClientCore( + services, + serviceKey, + settingsAction, + httpClientName); + } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/PublicAPI/net10.0/PublicAPI.txt b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net10.0/PublicAPI.txt new file mode 100644 index 000000000..9e5637073 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net10.0/PublicAPI.txt @@ -0,0 +1,56 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public static class HttpClientFactoryReflectionExtensions +{ + extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + } + extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/PublicAPI/net11.0/PublicAPI.txt b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net11.0/PublicAPI.txt new file mode 100644 index 000000000..9e5637073 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net11.0/PublicAPI.txt @@ -0,0 +1,56 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public static class HttpClientFactoryReflectionExtensions +{ + extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + } + extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } + [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/PublicAPI/net462/PublicAPI.txt b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net462/PublicAPI.txt new file mode 100644 index 000000000..691847714 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net462/PublicAPI.txt @@ -0,0 +1,44 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public static class HttpClientFactoryReflectionExtensions +{ + extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + } + extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/PublicAPI/net470/PublicAPI.txt b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net470/PublicAPI.txt new file mode 100644 index 000000000..691847714 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net470/PublicAPI.txt @@ -0,0 +1,44 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public static class HttpClientFactoryReflectionExtensions +{ + extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + } + extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/PublicAPI/net471/PublicAPI.txt b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net471/PublicAPI.txt new file mode 100644 index 000000000..691847714 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net471/PublicAPI.txt @@ -0,0 +1,44 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public static class HttpClientFactoryReflectionExtensions +{ + extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + } + extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/PublicAPI/net472/PublicAPI.txt b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net472/PublicAPI.txt new file mode 100644 index 000000000..691847714 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net472/PublicAPI.txt @@ -0,0 +1,44 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public static class HttpClientFactoryReflectionExtensions +{ + extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + } + extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/PublicAPI/net48/PublicAPI.txt b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net48/PublicAPI.txt new file mode 100644 index 000000000..691847714 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net48/PublicAPI.txt @@ -0,0 +1,44 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public static class HttpClientFactoryReflectionExtensions +{ + extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + } + extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/PublicAPI/net481/PublicAPI.txt b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net481/PublicAPI.txt new file mode 100644 index 000000000..691847714 --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/PublicAPI/net481/PublicAPI.txt @@ -0,0 +1,44 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public static class HttpClientFactoryReflectionExtensions +{ + extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + } + extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) + { + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } + public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } + } +} diff --git a/src/Refit.HttpClientFactory.Reflection/Refit.HttpClientFactory.Reflection.csproj b/src/Refit.HttpClientFactory.Reflection/Refit.HttpClientFactory.Reflection.csproj new file mode 100644 index 000000000..04ac3a5fa --- /dev/null +++ b/src/Refit.HttpClientFactory.Reflection/Refit.HttpClientFactory.Reflection.csproj @@ -0,0 +1,28 @@ + + + + Refit.HttpClientFactory.Reflection ($(TargetFramework)) + The opt-in reflection registration methods for Refit and HttpClientFactory. Install this package to use AddRefitClient and AddKeyedRefitClient, which build requests by reflection. Applications that only use generated clients and AddRefitGeneratedClient never need it. + refit;rest;http;httpclient;httpclientfactory;dependency-injection;reflection + $(RefitTargets) + Refit + enable + false + false + false + false + + + + + + + + + + + + + + + diff --git a/src/Refit.HttpClientFactory/HttpClientFactoryCore.cs b/src/Refit.HttpClientFactory/HttpClientFactoryCore.cs index 1d22267c4..38045302d 100644 --- a/src/Refit.HttpClientFactory/HttpClientFactoryCore.cs +++ b/src/Refit.HttpClientFactory/HttpClientFactoryCore.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. using System.Diagnostics.CodeAnalysis; -using System.Reflection; using Microsoft.Extensions.DependencyInjection; namespace Refit; @@ -10,263 +9,6 @@ namespace Refit; /// Shared registration logic backing the Refit HttpClientFactory extension methods. internal static class HttpClientFactoryCore { - /// Diagnostic message explaining why the reflection-based registration path is not trim-safe. - private const string RequiresUnreferencedCodeMessage = - "Registering Refit clients with HttpClientFactory requires reflected interface and request metadata."; - - /// Diagnostic message explaining why the reflection-based registration path is not AOT-safe. - private const string RequiresDynamicCodeMessage = - "Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation."; - - /// Lazily cached generic RequestBuilder.ForType method used to build request builders by type. - private static MethodInfo? _requestBuilderGenericForTypeMethod; - - /// Registers a Refit client and its dependencies for the given interface type. - /// The service collection to register into. - /// The Refit interface type to register. - /// A factory that produces the Refit settings, or null. - /// A name for the underlying HTTP client, or null. - /// The HTTP client builder for further configuration. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - internal static IHttpClientBuilder AddRefitClientCore( - IServiceCollection services, - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - Func? settings, - string? httpClientName) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - // register settings - var settingsType = typeof(SettingsFor<>).MakeGenericType(refitInterfaceType); - _ = services.AddSingleton( - settingsType, - provider => Activator.CreateInstance( - typeof(SettingsFor<>).MakeGenericType(refitInterfaceType), - settings?.Invoke(provider))!); - - // register RequestBuilder - var requestBuilderType = typeof(IRequestBuilder<>).MakeGenericType(refitInterfaceType); - _ = services.AddSingleton( - requestBuilderType, - provider => GetRequestBuilderGenericForTypeMethod() - .MakeGenericMethod(refitInterfaceType) - .Invoke( - null, - [((ISettingsFor)provider.GetRequiredService(settingsType)).Settings])!); - - // create HttpClientBuilder - var builder = services.AddHttpClient(httpClientName ?? UniqueName.ForType(refitInterfaceType)); - - // configure the primary handler from the supplied settings (or fall back to the default) - _ = builder.ConfigurePrimaryHttpMessageHandler(serviceProvider => - CreateInnerHandlerIfProvided( - ((ISettingsFor)serviceProvider.GetRequiredService(settingsType)).Settings) - ?? new HttpClientHandler()); - - // add typed client (register transient that resolves HttpClient from IHttpClientFactory and creates Refit client) - _ = builder.Services.AddTransient( - refitInterfaceType, - s => - { - var httpClientFactory = s.GetRequiredService(); - var httpClient = httpClientFactory.CreateClient(builder.Name); - return RestService.For( - refitInterfaceType, - httpClient, - (IRequestBuilder)s.GetRequiredService(requestBuilderType)); - }); - - return builder; - } - - /// Registers a strongly typed Refit client and its dependencies. - /// The Refit interface type to register. - /// The service collection to register into. - /// A factory that produces the Refit settings, or null. - /// A name for the underlying HTTP client, or null. - /// The HTTP client builder for further configuration. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - internal static IHttpClientBuilder AddRefitClientCore< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - IServiceCollection services, - Func? settings, - string? httpClientName) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - // register settings - _ = services.AddSingleton(provider => new SettingsFor(settings?.Invoke(provider))); - - // register RequestBuilder - _ = services.AddSingleton(static provider => - RequestBuilder.ForType(provider.GetRequiredService>().Settings)); - - // create HttpClientBuilder - var builder = services.AddHttpClient(httpClientName ?? UniqueName.ForType()); - - // configure the primary handler from the supplied settings (or fall back to the default) - _ = builder.ConfigurePrimaryHttpMessageHandler(static serviceProvider => - CreateInnerHandlerIfProvided( - serviceProvider.GetRequiredService>().Settings) - ?? new HttpClientHandler()); - - // add typed client using framework AddTypedClient - return builder.AddTypedClient(static (client, serviceProvider) => - RestService.For( - client, - serviceProvider.GetRequiredService>())); - } - - /// Registers a keyed Refit client and its dependencies for the given interface type. - /// The service collection to register into. - /// The Refit interface type to register. - /// The key under which the client is registered. - /// A factory that produces the Refit settings, or null. - /// A name for the underlying HTTP client, or null. - /// The HTTP client builder for further configuration. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - internal static IHttpClientBuilder AddKeyedRefitClientCore( - IServiceCollection services, - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - object? serviceKey, - Func? settings, - string? httpClientName) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - // register settings - var settingsType = typeof(SettingsFor<>).MakeGenericType(refitInterfaceType); - _ = services.AddKeyedSingleton( - settingsType, - serviceKey, - (provider, _) => Activator.CreateInstance( - typeof(SettingsFor<>).MakeGenericType(refitInterfaceType), - settings?.Invoke(provider))!); - - // register RequestBuilder - var requestBuilderType = typeof(IRequestBuilder<>).MakeGenericType(refitInterfaceType); - _ = services.AddKeyedSingleton( - requestBuilderType, - serviceKey, - (provider, _) => GetRequestBuilderGenericForTypeMethod() - .MakeGenericMethod(refitInterfaceType) - .Invoke( - null, - [((ISettingsFor)provider.GetRequiredKeyedService(settingsType, serviceKey)).Settings])!); - - // create HttpClientBuilder - var builder = services.AddHttpClient(httpClientName ?? UniqueName.ForType(refitInterfaceType, serviceKey)); - - // configure primary and additional handlers from the keyed settings - ConfigureKeyedHandlers( - builder, - serviceProvider => (ISettingsFor)serviceProvider.GetRequiredKeyedService(settingsType, serviceKey)); - - // add keyed typed client (register keyed transient that resolves HttpClient and creates Refit client) - _ = builder.Services.AddKeyedTransient( - refitInterfaceType, - serviceKey, - (s, _) => - { - var httpClientFactory = s.GetRequiredService(); - var httpClient = httpClientFactory.CreateClient(builder.Name); - return RestService.For( - refitInterfaceType, - httpClient, - (IRequestBuilder)s.GetRequiredKeyedService(requestBuilderType, serviceKey)); - }); - - return builder; - } - - /// Registers a strongly typed keyed Refit client and its dependencies. - /// The Refit interface type to register. - /// The service collection to register into. - /// The key under which the client is registered. - /// A factory that produces the Refit settings, or null. - /// A name for the underlying HTTP client, or null. - /// The HTTP client builder for further configuration. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - internal static IHttpClientBuilder AddKeyedRefitClientCore< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - IServiceCollection services, - object? serviceKey, - Func? settings, - string? httpClientName) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - // register settings - _ = services.AddKeyedSingleton( - serviceKey, - (provider, _) => new SettingsFor(settings?.Invoke(provider))); - - // register RequestBuilder - _ = services.AddKeyedSingleton( - serviceKey, - (provider, _) => - RequestBuilder.ForType( - provider.GetRequiredKeyedService>(serviceKey).Settings)); - - // create HttpClientBuilder - var builder = services.AddHttpClient(httpClientName ?? UniqueName.ForType(serviceKey)); - - // configure primary and additional handlers from the keyed settings - ConfigureKeyedHandlers( - builder, - serviceProvider => serviceProvider.GetRequiredKeyedService>(serviceKey)); - - // add keyed typed client (inline keyed registration) - _ = builder.Services.AddKeyedTransient( - serviceKey, - (s, _) => - { - var httpClientFactory = s.GetRequiredService(); - var httpClient = httpClientFactory.CreateClient(builder.Name); - return RestService.For( - httpClient, - s.GetRequiredKeyedService>(serviceKey)); - }); - - return builder; - } - /// Registers a strongly typed, source-generated Refit client without any reflection fallback. /// The Refit interface type to register. /// The service collection to register into. @@ -373,44 +115,10 @@ internal static IHttpClientBuilder AddKeyedRefitGeneratedClientCore( } #endif - /// Resolves and caches the open generic method. - /// The open generic RequestBuilder.ForType method definition. - [RequiresUnreferencedCode("Resolving RequestBuilder.ForType by reflection requires method metadata to be available at runtime.")] - private static MethodInfo GetRequestBuilderGenericForTypeMethod() => - _requestBuilderGenericForTypeMethod ??= FindRequestBuilderGenericForTypeMethod(); - - /// Finds the open generic method. - /// The matching method definition. - /// declares no single-parameter generic ForType method, or more than one. - [RequiresUnreferencedCode("Resolving RequestBuilder.ForType by reflection requires method metadata to be available at runtime.")] - [ExcludeFromCodeCoverage] // RequestBuilder declares exactly one single-parameter generic ForType, so the duplicate-match and no-match guards are unreachable. - private static MethodInfo FindRequestBuilderGenericForTypeMethod() - { - var methods = typeof(RequestBuilder).GetMethods(BindingFlags.Public | BindingFlags.Static); - MethodInfo? match = null; - for (var i = 0; i < methods.Length; i++) - { - var method = methods[i]; - if (!method.IsGenericMethodDefinition || method.GetParameters().Length != 1) - { - continue; - } - - if (match is not null) - { - throw new InvalidOperationException("Sequence contains more than one matching element"); - } - - match = method; - } - - return match ?? throw new InvalidOperationException("Sequence contains no matching element"); - } - /// Configures the primary and authorization handlers for a keyed Refit client from its settings. /// The HTTP client builder to configure. /// Resolves the settings holder for the keyed client from a service provider. - private static void ConfigureKeyedHandlers( + internal static void ConfigureKeyedHandlers( IHttpClientBuilder builder, Func settingsResolver) { @@ -431,7 +139,7 @@ private static void ConfigureKeyedHandlers( /// Builds the inner HTTP message handler from the supplied settings, if any. /// The Refit settings that may provide a handler factory or auth getter. /// The configured inner handler, or null when none is required. - private static HttpMessageHandler? CreateInnerHandlerIfProvided(RefitSettings? settings) + internal static HttpMessageHandler? CreateInnerHandlerIfProvided(RefitSettings? settings) { HttpMessageHandler? innerHandler = null; if (settings is not null) diff --git a/src/Refit.HttpClientFactory/HttpClientFactoryExtensions.HttpClientBuilder.cs b/src/Refit.HttpClientFactory/HttpClientFactoryExtensions.HttpClientBuilder.cs index 45459c921..b33706e03 100644 --- a/src/Refit.HttpClientFactory/HttpClientFactoryExtensions.HttpClientBuilder.cs +++ b/src/Refit.HttpClientFactory/HttpClientFactoryExtensions.HttpClientBuilder.cs @@ -1,7 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.DependencyInjection; namespace Refit; @@ -13,310 +12,6 @@ public static partial class HttpClientFactoryExtensions /// The HTTP client builder the Refit client is registered with. extension(IHttpClientBuilder builder) { - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddRefitClient(Type refitInterfaceType) - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - return HttpClientFactoryCore.AddRefitClientCore( - builder.Services, - refitInterfaceType, - static _ => null, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The settings used to configure the instance. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddRefitClient( - Type refitInterfaceType, - RefitSettings? settings) - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - return HttpClientFactoryCore.AddRefitClientCore( - builder.Services, - refitInterfaceType, - _ => settings, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// An action used to configure the Refit settings from the service provider. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddRefitClient( - Type refitInterfaceType, - Func? settingsAction) - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - return HttpClientFactoryCore.AddRefitClientCore( - builder.Services, - refitInterfaceType, - settingsAction, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>() - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - return HttpClientFactoryCore.AddRefitClientCore( - builder.Services, - static _ => null, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The settings used to configure the instance. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(RefitSettings? settings) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - return HttpClientFactoryCore.AddRefitClientCore( - builder.Services, - _ => settings, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// An action used to configure the Refit settings from the service provider. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(Func? settingsAction) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - return HttpClientFactoryCore.AddRefitClientCore( - builder.Services, - settingsAction, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient( - Type refitInterfaceType, - object? serviceKey) - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - builder.Services, - refitInterfaceType, - serviceKey, - static _ => null, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The settings used to configure the instance. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient( - Type refitInterfaceType, - object? serviceKey, - RefitSettings? settings) - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - builder.Services, - refitInterfaceType, - serviceKey, - _ => settings, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// An action used to configure the Refit settings from the service provider. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient( - Type refitInterfaceType, - object? serviceKey, - Func? settingsAction) - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - builder.Services, - refitInterfaceType, - serviceKey, - settingsAction, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(object? serviceKey) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - builder.Services, - serviceKey, - static _ => null, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The settings used to configure the instance. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - object? serviceKey, - RefitSettings? settings) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - builder.Services, - serviceKey, - _ => settings, - builder.Name); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// An action used to configure the Refit settings from the service provider. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - object? serviceKey, - Func? settingsAction) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(builder); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - builder.Services, - serviceKey, - settingsAction, - builder.Name); - } - /// Adds a message handler that resolves each request's authorization token from a fresh dependency-injection scope. /// /// A delegate that resolves the authorization token from a per-request , the outgoing diff --git a/src/Refit.HttpClientFactory/HttpClientFactoryExtensions.ServiceCollection.cs b/src/Refit.HttpClientFactory/HttpClientFactoryExtensions.ServiceCollection.cs index 85f45d989..d390c138d 100644 --- a/src/Refit.HttpClientFactory/HttpClientFactoryExtensions.ServiceCollection.cs +++ b/src/Refit.HttpClientFactory/HttpClientFactoryExtensions.ServiceCollection.cs @@ -9,550 +9,10 @@ namespace Refit; /// Extension methods for registering Refit clients with dependency injection. public static partial class HttpClientFactoryExtensions { - /// Diagnostic message explaining why the reflection-based registration path is not trim-safe. - private const string RequiresUnreferencedCodeMessage = - "Registering Refit clients with HttpClientFactory requires reflected interface and request metadata."; - - /// Diagnostic message explaining why the reflection-based registration path is not AOT-safe. - private const string RequiresDynamicCodeMessage = - "Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation."; - /// Registers Refit clients directly on an . /// The service collection the Refit client is registered with. extension(IServiceCollection services) { - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddRefitClient(Type refitInterfaceType) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - refitInterfaceType, - static _ => null, - null); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The settings used to configure the instance. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddRefitClient( - Type refitInterfaceType, - RefitSettings? settings) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - refitInterfaceType, - _ => settings, - null); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The settings used to configure the instance. - /// Allows the name of the underlying HttpClient to be changed. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddRefitClient( - Type refitInterfaceType, - RefitSettings? settings, - string? httpClientName) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - refitInterfaceType, - _ => settings, - httpClientName); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// An action used to configure the Refit settings from the service provider. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddRefitClient( - Type refitInterfaceType, - Func? settingsAction) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - refitInterfaceType, - settingsAction, - null); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// An action used to configure the Refit settings from the service provider. - /// Allows the name of the underlying HttpClient to be changed. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddRefitClient( - Type refitInterfaceType, - Func? settingsAction, - string? httpClientName) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - refitInterfaceType, - settingsAction, - httpClientName); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>() - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - static _ => null, - null); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The settings used to configure the instance. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(RefitSettings? settings) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - _ => settings, - null); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// The settings used to configure the instance. - /// Allows the name of the underlying HttpClient to be changed. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - RefitSettings? settings, - string? httpClientName) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - _ => settings, - httpClientName); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// An action used to configure the Refit settings from the service provider. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(Func? settingsAction) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - settingsAction, - null); - } - - /// Adds a Refit client to the dependency injection container. - /// The type of the Refit interface. - /// An action used to configure the Refit settings from the service provider. - /// Allows the name of the underlying HttpClient to be changed. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - Func? settingsAction, - string? httpClientName) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - return HttpClientFactoryCore.AddRefitClientCore( - services, - settingsAction, - httpClientName); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient( - Type refitInterfaceType, - object? serviceKey) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - refitInterfaceType, - serviceKey, - static _ => null, - null); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The settings used to configure the instance. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient( - Type refitInterfaceType, - object? serviceKey, - RefitSettings? settings) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - refitInterfaceType, - serviceKey, - _ => settings, - null); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The settings used to configure the instance. - /// Allows the name of the underlying HttpClient to be changed. - /// The HTTP client builder for chaining. - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient( - Type refitInterfaceType, - object? serviceKey, - RefitSettings? settings, - string? httpClientName) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - refitInterfaceType, - serviceKey, - _ => settings, - httpClientName); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// An action used to configure the Refit settings from the service provider. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient( - Type refitInterfaceType, - object? serviceKey, - Func? settingsAction) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - refitInterfaceType, - serviceKey, - settingsAction, - null); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// An action used to configure the Refit settings from the service provider. - /// Allows the name of the underlying HttpClient to be changed. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - [RequiresDynamicCode(RequiresDynamicCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient( - Type refitInterfaceType, - object? serviceKey, - Func? settingsAction, - string? httpClientName) - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(refitInterfaceType); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - refitInterfaceType, - serviceKey, - settingsAction, - httpClientName); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(object? serviceKey) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - serviceKey, - static _ => null, - null); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The settings used to configure the instance. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - object? serviceKey, - RefitSettings? settings) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - serviceKey, - _ => settings, - null); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// The settings used to configure the instance. - /// Allows the name of the underlying HttpClient to be changed. - /// The HTTP client builder for chaining. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - object? serviceKey, - RefitSettings? settings, - string? httpClientName) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - serviceKey, - _ => settings, - httpClientName); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// An action used to configure the Refit settings from the service provider. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - object? serviceKey, - Func? settingsAction) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - serviceKey, - settingsAction, - null); - } - - /// Adds a Refit client to the dependency injection container with a specified service key. - /// The type of the Refit interface. - /// A key used to associate with the specific Refit client instance. - /// An action used to configure the Refit settings from the service provider. - /// Allows the name of the underlying HttpClient to be changed. - /// The HTTP client builder for chaining. - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "The Refit interface type is intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] - public IHttpClientBuilder AddKeyedRefitClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>( - object? serviceKey, - Func? settingsAction, - string? httpClientName) - where T : class - { - ArgumentExceptionHelper.ThrowIfNull(services); - - ArgumentExceptionHelper.ThrowIfNull(serviceKey); - - return HttpClientFactoryCore.AddKeyedRefitClientCore( - services, - serviceKey, - settingsAction, - httpClientName); - } - /// /// Adds a source-generated Refit client to the dependency injection container without any reflection /// fallback, making it safe for Native AOT and trimming. The client is built through diff --git a/src/Refit.HttpClientFactory/PublicAPI/net10.0/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net10.0/PublicAPI.txt index 2304f467f..ff485322e 100644 --- a/src/Refit.HttpClientFactory/PublicAPI/net10.0/PublicAPI.txt +++ b/src/Refit.HttpClientFactory/PublicAPI/net10.0/PublicAPI.txt @@ -1,3 +1,4 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Reflection")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] namespace Refit; @@ -6,40 +7,6 @@ public static class HttpClientFactoryExtensions extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { @@ -59,35 +26,6 @@ public static class HttpClientFactoryExtensions } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] @@ -95,35 +33,6 @@ public static class HttpClientFactoryExtensions public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] diff --git a/src/Refit.HttpClientFactory/PublicAPI/net11.0/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net11.0/PublicAPI.txt index 2304f467f..ff485322e 100644 --- a/src/Refit.HttpClientFactory/PublicAPI/net11.0/PublicAPI.txt +++ b/src/Refit.HttpClientFactory/PublicAPI/net11.0/PublicAPI.txt @@ -1,3 +1,4 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Reflection")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] namespace Refit; @@ -6,40 +7,6 @@ public static class HttpClientFactoryExtensions extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { @@ -59,35 +26,6 @@ public static class HttpClientFactoryExtensions } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] @@ -95,35 +33,6 @@ public static class HttpClientFactoryExtensions public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] diff --git a/src/Refit.HttpClientFactory/PublicAPI/net462/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net462/PublicAPI.txt index bf455d774..62e9b1516 100644 --- a/src/Refit.HttpClientFactory/PublicAPI/net462/PublicAPI.txt +++ b/src/Refit.HttpClientFactory/PublicAPI/net462/PublicAPI.txt @@ -1,3 +1,4 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Reflection")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] namespace Refit; @@ -6,46 +7,14 @@ public static class HttpClientFactoryExtensions extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction) where T : class { } diff --git a/src/Refit.HttpClientFactory/PublicAPI/net470/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net470/PublicAPI.txt index bf455d774..62e9b1516 100644 --- a/src/Refit.HttpClientFactory/PublicAPI/net470/PublicAPI.txt +++ b/src/Refit.HttpClientFactory/PublicAPI/net470/PublicAPI.txt @@ -1,3 +1,4 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Reflection")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] namespace Refit; @@ -6,46 +7,14 @@ public static class HttpClientFactoryExtensions extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction) where T : class { } diff --git a/src/Refit.HttpClientFactory/PublicAPI/net471/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net471/PublicAPI.txt index bf455d774..62e9b1516 100644 --- a/src/Refit.HttpClientFactory/PublicAPI/net471/PublicAPI.txt +++ b/src/Refit.HttpClientFactory/PublicAPI/net471/PublicAPI.txt @@ -1,3 +1,4 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Reflection")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] namespace Refit; @@ -6,46 +7,14 @@ public static class HttpClientFactoryExtensions extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction) where T : class { } diff --git a/src/Refit.HttpClientFactory/PublicAPI/net472/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net472/PublicAPI.txt index bf455d774..62e9b1516 100644 --- a/src/Refit.HttpClientFactory/PublicAPI/net472/PublicAPI.txt +++ b/src/Refit.HttpClientFactory/PublicAPI/net472/PublicAPI.txt @@ -1,3 +1,4 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Reflection")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] namespace Refit; @@ -6,46 +7,14 @@ public static class HttpClientFactoryExtensions extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction) where T : class { } diff --git a/src/Refit.HttpClientFactory/PublicAPI/net48/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net48/PublicAPI.txt index bf455d774..62e9b1516 100644 --- a/src/Refit.HttpClientFactory/PublicAPI/net48/PublicAPI.txt +++ b/src/Refit.HttpClientFactory/PublicAPI/net48/PublicAPI.txt @@ -1,3 +1,4 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Reflection")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] namespace Refit; @@ -6,46 +7,14 @@ public static class HttpClientFactoryExtensions extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction) where T : class { } diff --git a/src/Refit.HttpClientFactory/PublicAPI/net481/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net481/PublicAPI.txt index bf455d774..62e9b1516 100644 --- a/src/Refit.HttpClientFactory/PublicAPI/net481/PublicAPI.txt +++ b/src/Refit.HttpClientFactory/PublicAPI/net481/PublicAPI.txt @@ -1,3 +1,4 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Reflection")] [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] namespace Refit; @@ -6,46 +7,14 @@ public static class HttpClientFactoryExtensions extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) { public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } } extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction) where T : class { } diff --git a/src/Refit.HttpClientFactory/PublicAPI/net8.0/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net8.0/PublicAPI.txt deleted file mode 100644 index 9acc6a374..000000000 --- a/src/Refit.HttpClientFactory/PublicAPI/net8.0/PublicAPI.txt +++ /dev/null @@ -1,124 +0,0 @@ -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] -namespace Refit; - -public static class HttpClientFactoryExtensions -{ - extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) - { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - } - extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) - { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Text.Json.Serialization.JsonSerializerContext context) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction, string? httpClientName, bool allowReflectionFallback) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction, string? httpClientName, bool allowReflectionFallback) where T : class { } - } - extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) - { - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction, string? httpClientName) where T : class { } - } -} -public interface ISettingsFor -{ - Refit.RefitSettings? Settings { get; } -} -[System.Diagnostics.DebuggerDisplay("SettingsFor: {Settings}")] -public class SettingsFor : Refit.ISettingsFor -{ - public SettingsFor(Refit.RefitSettings? settings) { } - public Refit.RefitSettings? Settings { get; } -} diff --git a/src/Refit.HttpClientFactory/PublicAPI/net9.0/PublicAPI.txt b/src/Refit.HttpClientFactory/PublicAPI/net9.0/PublicAPI.txt deleted file mode 100644 index 2304f467f..000000000 --- a/src/Refit.HttpClientFactory/PublicAPI/net9.0/PublicAPI.txt +++ /dev/null @@ -1,145 +0,0 @@ -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory.Tests")] -namespace Refit; - -public static class HttpClientFactoryExtensions -{ - extension(Microsoft.Extensions.DependencyInjection.IHttpClientBuilder builder) - { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddAuthorizationHeaderValueProvider(System.Func> getToken) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - } - extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) - { - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Text.Json.Serialization.JsonSerializerContext context) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction, string? httpClientName, bool allowReflectionFallback) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction, string? httpClientName) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Text.Json.Serialization.JsonSerializerContext context, System.Func? settingsAction, string? httpClientName, bool allowReflectionFallback) where T : class { } - } - extension(Microsoft.Extensions.DependencyInjection.IServiceCollection services) - { - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(System.Type refitInterfaceType, object? serviceKey, System.Func? settingsAction, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddKeyedRefitGeneratedClient(object? serviceKey, System.Func? settingsAction, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, Refit.RefitSettings? settings, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Registering Refit clients by Type with HttpClientFactory requires runtime generic type and method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Type refitInterfaceType, System.Func? settingsAction, string? httpClientName) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient() where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Registering Refit clients with HttpClientFactory requires reflected interface and request metadata.")] - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitClient(System.Func? settingsAction, string? httpClientName) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient() where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction) where T : class { } - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(Refit.RefitSettings? settings, string? httpClientName) where T : class { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public Microsoft.Extensions.DependencyInjection.IHttpClientBuilder AddRefitGeneratedClient(System.Func? settingsAction, string? httpClientName) where T : class { } - } -} -public interface ISettingsFor -{ - Refit.RefitSettings? Settings { get; } -} -[System.Diagnostics.DebuggerDisplay("SettingsFor: {Settings}")] -public class SettingsFor : Refit.ISettingsFor -{ - public SettingsFor(Refit.RefitSettings? settings) { } - public Refit.RefitSettings? Settings { get; } -} diff --git a/src/Refit.HttpClientFactory/Refit.HttpClientFactory.csproj b/src/Refit.HttpClientFactory/Refit.HttpClientFactory.csproj index ce2b17300..4fef96271 100644 --- a/src/Refit.HttpClientFactory/Refit.HttpClientFactory.csproj +++ b/src/Refit.HttpClientFactory/Refit.HttpClientFactory.csproj @@ -12,6 +12,7 @@ + diff --git a/src/Refit.NativeAotSmoke/AotJsonContext.cs b/src/Refit.NativeAotSmoke/AotJsonContext.cs index bfeb040ed..999d79218 100644 --- a/src/Refit.NativeAotSmoke/AotJsonContext.cs +++ b/src/Refit.NativeAotSmoke/AotJsonContext.cs @@ -11,5 +11,6 @@ namespace Refit.NativeAotSmoke; [JsonSerializable(typeof(SmokeRecord))] [JsonSourceGenerationOptions( PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - PropertyNameCaseInsensitive = true)] + PropertyNameCaseInsensitive = true, + UseStringEnumConverter = true)] internal sealed partial class AotJsonContext : JsonSerializerContext; diff --git a/src/Refit.NetFrameworkSmoke/Program.cs b/src/Refit.NetFrameworkSmoke/Program.cs index 7e582333c..fc0eb764b 100644 --- a/src/Refit.NetFrameworkSmoke/Program.cs +++ b/src/Refit.NetFrameworkSmoke/Program.cs @@ -10,12 +10,15 @@ const string MissingClientFragment = "doesn't look like a Refit interface"; +// The smoke types have no source-generated JSON context, so typed replies need the reflection-based metadata. +ReflectionSupport.EnsureRegistered(); + var handler = new NetFrameworkSmokeHandler(); using var client = new HttpClient(handler) { BaseAddress = new("https://netfx.refit.test") }; -// .NET Framework has no [ModuleInitializer], so the generator emits no factory registrations here and the registries -// stay empty. ForGenerated has to resolve the generated implementation by name for any of this to work at all. +// .NET Framework does not define [ModuleInitializer], so the generator declares the attribute itself. The compiler still +// lowers it into the module constructor, which registers the generated factories when ForGenerated runs it. var api = RestService.ForGenerated(client); var fetched = await api.GetTodoAsync(ExpectedTodoId).ConfigureAwait(false); diff --git a/src/Refit.NetFrameworkSmoke/Refit.NetFrameworkSmoke.csproj b/src/Refit.NetFrameworkSmoke/Refit.NetFrameworkSmoke.csproj index 47993c046..c68bb77f6 100644 --- a/src/Refit.NetFrameworkSmoke/Refit.NetFrameworkSmoke.csproj +++ b/src/Refit.NetFrameworkSmoke/Refit.NetFrameworkSmoke.csproj @@ -6,6 +6,7 @@ + diff --git a/src/Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs b/src/Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs index 62661b8b5..3fe39345d 100644 --- a/src/Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs +++ b/src/Refit.Newtonsoft.Json/NewtonsoftJsonContentSerializer.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. using System.Diagnostics.CodeAnalysis; -using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using Newtonsoft.Json; @@ -16,7 +15,7 @@ namespace Refit; /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public sealed class NewtonsoftJsonContentSerializer( - JsonSerializerSettings? jsonSerializerSettings) : IHttpContentSerializer, ISynchronousContentDeserializer + JsonSerializerSettings? jsonSerializerSettings) : IHttpContentSerializer, ISynchronousContentDeserializer, IContentSerializerNameStyle { /// The number of characters consumed by a leading and trailing quote pair around a charset value. private const int QuotePairLength = 2; @@ -49,16 +48,11 @@ public NewtonsoftJsonContentSerializer() { } + /// + public ContentSerializerNameStyle NameStyle => ContentSerializerNameStyle.Newtonsoft; + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage( - "Trimming", - "IL2026:Members annotated with RequiresUnreferencedCodeAttribute may break when trimming", - Justification = "Interface method is unannotated on net8.0+ so cannot propagate; Newtonsoft path is documented as unsuitable for trimmed/AOT apps.")] - [UnconditionalSuppressMessage( - "AOT", - "IL3050:Calling members annotated with RequiresDynamicCodeAttribute may break when AOT compiling", - Justification = "Interface method is unannotated on net8.0+ so cannot propagate; Newtonsoft path is documented as unsuitable for trimmed/AOT apps.")] public HttpContent ToHttpContent(T item) => new StringContent( JsonConvert.SerializeObject(item, _jsonSerializerSettings.Value), @@ -66,14 +60,6 @@ public HttpContent ToHttpContent(T item) => "application/json"); /// - [UnconditionalSuppressMessage( - "Trimming", - "IL2026:Members annotated with RequiresUnreferencedCodeAttribute may break when trimming", - Justification = "Interface method is unannotated on net8.0+ so cannot propagate; Newtonsoft path is documented as unsuitable for trimmed/AOT apps.")] - [UnconditionalSuppressMessage( - "AOT", - "IL3050:Calling members annotated with RequiresDynamicCodeAttribute may break when AOT compiling", - Justification = "Interface method is unannotated on net8.0+ so cannot propagate; Newtonsoft path is documented as unsuitable for trimmed/AOT apps.")] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", @@ -117,14 +103,6 @@ public HttpContent ToHttpContent(T item) => /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage( - "Trimming", - "IL2026:Members annotated with RequiresUnreferencedCodeAttribute may break when trimming", - Justification = "Interface method is unannotated on net8.0+ so cannot propagate; Newtonsoft path is documented as unsuitable for trimmed/AOT apps.")] - [UnconditionalSuppressMessage( - "AOT", - "IL3050:Calling members annotated with RequiresDynamicCodeAttribute may break when AOT compiling", - Justification = "Interface method is unannotated on net8.0+ so cannot propagate; Newtonsoft path is documented as unsuitable for trimmed/AOT apps.")] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", @@ -132,20 +110,6 @@ public HttpContent ToHttpContent(T item) => public T? DeserializeFromString(string content) => JsonConvert.DeserializeObject(content, _jsonSerializerSettings.Value); - /// - /// Calculates what the field name should be for the given property. This may be affected by custom attributes the serializer understands. - /// - /// A PropertyInfo object. - /// - /// The calculated field name. - /// - /// propertyInfo - public string? GetFieldNameForProperty(PropertyInfo propertyInfo) - { - ArgumentExceptionHelper.ThrowIfNull(propertyInfo); - return propertyInfo.GetCustomAttribute(true)?.PropertyName; - } - /// Resolves the text encoding from the content type charset, if present. /// The HTTP content to inspect. /// The resolved encoding, or null when no charset is specified. diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net10.0/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net10.0/PublicAPI.txt index 2c189b711..eead56951 100644 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net10.0/PublicAPI.txt +++ b/src/Refit.Newtonsoft.Json/PublicAPI/net10.0/PublicAPI.txt @@ -1,14 +1,14 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public sealed class NewtonsoftJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public NewtonsoftJsonContentSerializer() { } public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Net.Http.HttpContent ToHttpContent(T item) { } } diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net11.0/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net11.0/PublicAPI.txt index 2c189b711..eead56951 100644 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net11.0/PublicAPI.txt +++ b/src/Refit.Newtonsoft.Json/PublicAPI/net11.0/PublicAPI.txt @@ -1,14 +1,14 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public sealed class NewtonsoftJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public NewtonsoftJsonContentSerializer() { } public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Net.Http.HttpContent ToHttpContent(T item) { } } diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net462/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net462/PublicAPI.txt index 2c189b711..eead56951 100644 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net462/PublicAPI.txt +++ b/src/Refit.Newtonsoft.Json/PublicAPI/net462/PublicAPI.txt @@ -1,14 +1,14 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public sealed class NewtonsoftJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public NewtonsoftJsonContentSerializer() { } public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Net.Http.HttpContent ToHttpContent(T item) { } } diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net470/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net470/PublicAPI.txt index 2c189b711..eead56951 100644 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net470/PublicAPI.txt +++ b/src/Refit.Newtonsoft.Json/PublicAPI/net470/PublicAPI.txt @@ -1,14 +1,14 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public sealed class NewtonsoftJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public NewtonsoftJsonContentSerializer() { } public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Net.Http.HttpContent ToHttpContent(T item) { } } diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net471/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net471/PublicAPI.txt index 2c189b711..eead56951 100644 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net471/PublicAPI.txt +++ b/src/Refit.Newtonsoft.Json/PublicAPI/net471/PublicAPI.txt @@ -1,14 +1,14 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public sealed class NewtonsoftJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public NewtonsoftJsonContentSerializer() { } public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Net.Http.HttpContent ToHttpContent(T item) { } } diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net472/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net472/PublicAPI.txt index 2c189b711..eead56951 100644 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net472/PublicAPI.txt +++ b/src/Refit.Newtonsoft.Json/PublicAPI/net472/PublicAPI.txt @@ -1,14 +1,14 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public sealed class NewtonsoftJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public NewtonsoftJsonContentSerializer() { } public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Net.Http.HttpContent ToHttpContent(T item) { } } diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net48/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net48/PublicAPI.txt index 2c189b711..eead56951 100644 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net48/PublicAPI.txt +++ b/src/Refit.Newtonsoft.Json/PublicAPI/net48/PublicAPI.txt @@ -1,14 +1,14 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public sealed class NewtonsoftJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public NewtonsoftJsonContentSerializer() { } public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Net.Http.HttpContent ToHttpContent(T item) { } } diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net481/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net481/PublicAPI.txt index 2c189b711..eead56951 100644 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net481/PublicAPI.txt +++ b/src/Refit.Newtonsoft.Json/PublicAPI/net481/PublicAPI.txt @@ -1,14 +1,14 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public sealed class NewtonsoftJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public NewtonsoftJsonContentSerializer() { } public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Net.Http.HttpContent ToHttpContent(T item) { } } diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net8.0/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net8.0/PublicAPI.txt deleted file mode 100644 index 2c189b711..000000000 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net8.0/PublicAPI.txt +++ /dev/null @@ -1,14 +0,0 @@ -namespace Refit; - -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer -{ - public NewtonsoftJsonContentSerializer() { } - public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T? DeserializeFromString(string content) { } - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Net.Http.HttpContent ToHttpContent(T item) { } -} diff --git a/src/Refit.Newtonsoft.Json/PublicAPI/net9.0/PublicAPI.txt b/src/Refit.Newtonsoft.Json/PublicAPI/net9.0/PublicAPI.txt deleted file mode 100644 index 2c189b711..000000000 --- a/src/Refit.Newtonsoft.Json/PublicAPI/net9.0/PublicAPI.txt +++ /dev/null @@ -1,14 +0,0 @@ -namespace Refit; - -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NewtonsoftJsonContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer -{ - public NewtonsoftJsonContentSerializer() { } - public NewtonsoftJsonContentSerializer(Newtonsoft.Json.JsonSerializerSettings? jsonSerializerSettings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T? DeserializeFromString(string content) { } - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Net.Http.HttpContent ToHttpContent(T item) { } -} diff --git a/src/Refit.Newtonsoft.Json/Refit.Newtonsoft.Json.csproj b/src/Refit.Newtonsoft.Json/Refit.Newtonsoft.Json.csproj index 7c1073088..801f50aeb 100644 --- a/src/Refit.Newtonsoft.Json/Refit.Newtonsoft.Json.csproj +++ b/src/Refit.Newtonsoft.Json/Refit.Newtonsoft.Json.csproj @@ -5,7 +5,10 @@ Newtonsoft.Json content serializer for Refit clients that need Json.NET converters, settings, or compatibility behavior instead of the default System.Text.Json serializer. refit;rest;http;api-client;json;newtonsoft-json;json-net;serializer;content-serializer $(RefitShippingTargets) - true + false + false + false + false diff --git a/src/Refit.Reflection/CachedAttributeProvider.cs b/src/Refit.Reflection/CachedAttributeProvider.cs index b2952ecca..445ea1da6 100644 --- a/src/Refit.Reflection/CachedAttributeProvider.cs +++ b/src/Refit.Reflection/CachedAttributeProvider.cs @@ -15,7 +15,7 @@ namespace Refit; /// other query delegates to , so a custom formatter that reads other attributes sees exactly the /// same values it would from the original provider. The cached array holds immutable metadata attributes, so sharing it /// across format calls is behaviourally identical to re-reading it. -internal sealed class CachedAttributeProvider(ICustomAttributeProvider inner) : ICustomAttributeProvider +internal sealed class CachedAttributeProvider(ICustomAttributeProvider inner) : IParameterAttributeProvider { /// The materialized lookup, cached on first read. private object[]? _queryAttributes; diff --git a/src/Refit.Reflection/EnumMemberValues.cs b/src/Refit.Reflection/EnumMemberValues.cs new file mode 100644 index 000000000..50a3d574d --- /dev/null +++ b/src/Refit.Reflection/EnumMemberValues.cs @@ -0,0 +1,57 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Collections.Concurrent; +using System.Reflection; +using System.Runtime.Serialization; + +namespace Refit; + +/// Reads values from run-time-typed enums by reflection. +internal static class EnumMemberValues +{ + /// Caches lookups by enum type and field name. + private static readonly ConcurrentDictionary> _enumMemberValueCache = new(); + + /// Gets the for a boxed enum value. + /// The runtime enum type. + /// The boxed enum value. + /// The configured enum member value, or null when none is configured. + internal static string? GetEnumMemberValue(Type enumType, object value) + { + if (!enumType.IsEnum) + { + return null; + } + + var name = Enum.GetName(enumType, value); + if (name is null) + { + return null; + } + + var enumMemberValues = _enumMemberValueCache.GetOrAdd(enumType, CreateEnumMemberValueMap); + return enumMemberValues.TryGetValue(name, out var enumMemberValue) ? enumMemberValue : null; + } + + /// Builds the enum-member value map for the given enum type. + /// The enum type to inspect. + /// The enum-member value map keyed by enum field name. + internal static Dictionary CreateEnumMemberValueMap(Type enumType) + { + var fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); + var enumMemberValues = new Dictionary(fields.Length, StringComparer.Ordinal); + for (var i = 0; i < fields.Length; i++) + { + var field = fields[i]; + var enumMemberAttribute = field.GetCustomAttribute(); + if (enumMemberAttribute is not null) + { + enumMemberValues[field.Name] = enumMemberAttribute.Value; + } + } + + return enumMemberValues; + } +} diff --git a/src/Refit.Reflection/FormObjectFlattener.cs b/src/Refit.Reflection/FormObjectFlattener.cs new file mode 100644 index 000000000..36402cddf --- /dev/null +++ b/src/Refit.Reflection/FormObjectFlattener.cs @@ -0,0 +1,96 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Refit; + +/// Flattens complex form values by reading their public properties through reflection. +internal sealed class FormObjectFlattener : IFormObjectFlattener +{ + /// Caches the per-property attribute metadata for each source type without keeping collectible types alive. + /// The attributes are compile-time metadata that never change for a type, so they are read once and reused. + /// Field names still consult the settings' content serializer and key formatter per call, so settings-dependent + /// naming is never frozen. + private static readonly ConditionalWeakTable _metadataCache = new(); + + /// + public void AddObject( + FormValueMultimap map, + object source, + Type sourceType, + RefitSettings settings, + string? keyPrefix, + string? delimiter, + int depth) + { + var metadata = _metadataCache.GetValue(sourceType, BuildMetadata); + for (var i = 0; i < metadata.Length; i++) + { + var value = metadata[i].Property.GetValue(source, null); + + // The query attribute was read once when the metadata was cached for this type. + var attrib = metadata[i].Query; + + var fieldName = FormValueMultimap.ComposeKey(keyPrefix, GetFieldNameForProperty(map, metadata[i]), delimiter); + + if (value is null) + { + if (attrib?.SerializeNull == true) + { + map.Add(fieldName, string.Empty); + } + + continue; + } + + var collectionFormat = attrib?.IsCollectionFormatSpecified == true + ? attrib.CollectionFormat + : (CollectionFormat?)null; + + // A nested object/dictionary composes its children under this property's key using this property's own + // [Query] delimiter when present, otherwise the inherited delimiter (matching the query-flattening path). + var nestedDelimiter = attrib is not null ? attrib.Delimiter : (delimiter ?? FormValueMultimap.DefaultNestingDelimiter); + + map.AppendValue(fieldName, value, attrib?.Format, collectionFormat, settings, nestedDelimiter, depth); + } + } + + /// Reads the attribute metadata for each readable public property of the given type. + /// The type whose properties are inspected. + /// The attribute metadata array, in property order. + internal static FormPropertyMetadata[] BuildMetadata(Type type) + { + var properties = ReflectionPropertyHelpers.GetReadablePublicInstanceProperties(type); + var metadata = new FormPropertyMetadata[properties.Length]; + for (var i = 0; i < properties.Length; i++) + { + var property = properties[i]; + metadata[i] = new( + property, + property.GetCustomAttribute(true)?.Name, + property.GetCustomAttribute(true)); + } + + return metadata; + } + + /// Resolves the form field name for the given property from its cached attribute metadata. + /// The form map whose settings supply the content serializer and key formatter. + /// The cached attribute metadata for the property. + /// The resolved form field name. + internal static string GetFieldNameForProperty(FormValueMultimap map, in FormPropertyMetadata metadata) + { + var name = metadata.AliasName + ?? metadata.Query?.Name + ?? SerializerFieldNames.Resolve(map.ContentSerializer, metadata.Property) + ?? map.UrlParameterKeyFormatter.Format(metadata.Property.Name); + + var qattrib = metadata.Query; + return qattrib is not null && !string.IsNullOrWhiteSpace(qattrib.Prefix) + ? qattrib.Prefix + qattrib.Delimiter + name + : name; + } +} diff --git a/src/Refit.Reflection/FormPropertyMetadata.cs b/src/Refit.Reflection/FormPropertyMetadata.cs new file mode 100644 index 000000000..bbb73f8f7 --- /dev/null +++ b/src/Refit.Reflection/FormPropertyMetadata.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Reflection; + +namespace Refit; + +/// The cached, settings-independent attribute metadata for a single readable public property on a form +/// source type, read once when the property list is first cached and reused for every request. +/// The reflected property. +/// The override, or when absent. +/// The applied to the property, or when absent. +internal readonly record struct FormPropertyMetadata( + PropertyInfo Property, + string? AliasName, + QueryAttribute? Query); diff --git a/src/Refit.Reflection/GeneratedTypeResolver.cs b/src/Refit.Reflection/GeneratedTypeResolver.cs new file mode 100644 index 000000000..7218bfe6e --- /dev/null +++ b/src/Refit.Reflection/GeneratedTypeResolver.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit; + +/// Resolves generated implementation types by their emitted names. +internal static class GeneratedTypeResolver +{ + /// Resolves the generated implementation type for a Refit interface by its emitted name. + /// The Refit interface type. + /// The generated implementation type. + internal static Type Resolve(Type refitInterfaceType) => + Type.GetType(UniqueName.ForType(refitInterfaceType), false) + ?? throw RestService.CreateMissingGeneratedFactoryException(refitInterfaceType); +} diff --git a/src/Refit.Reflection/IReflectionFieldNameProvider.cs b/src/Refit.Reflection/IReflectionFieldNameProvider.cs new file mode 100644 index 000000000..260f6bb9f --- /dev/null +++ b/src/Refit.Reflection/IReflectionFieldNameProvider.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Reflection; + +namespace Refit; + +/// +/// Implemented by a custom content serializer to name form and query fields from the attributes it understands. +/// The built-in System.Text.Json, Newtonsoft.Json and XML serializers need no implementation: Refit reads their +/// attributes itself. +/// +public interface IReflectionFieldNameProvider +{ + /// + /// Calculates what the field name should be for the given property. This may be affected by custom attributes the serializer understands. + /// + /// A PropertyInfo object. + /// The calculated field name, or to use the default. + string? GetFieldNameForProperty(PropertyInfo propertyInfo); +} diff --git a/src/Refit/ObjectToInferredTypesConverter.cs b/src/Refit.Reflection/ObjectToInferredTypesConverter.cs similarity index 100% rename from src/Refit/ObjectToInferredTypesConverter.cs rename to src/Refit.Reflection/ObjectToInferredTypesConverter.cs diff --git a/src/Refit.Reflection/PublicAPI/net10.0/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net10.0/PublicAPI.txt index e69de29bb..f7c81f521 100644 --- a/src/Refit.Reflection/PublicAPI/net10.0/PublicAPI.txt +++ b/src/Refit.Reflection/PublicAPI/net10.0/PublicAPI.txt @@ -0,0 +1,93 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public interface IReflectionFieldNameProvider +{ + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter +{ + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } +} +public static class ReflectionJsonSerializerOptionsExtensions +{ + extension(System.Text.Json.JsonSerializerOptions options) + { + public System.Text.Json.JsonSerializerOptions AddReflectionConverters() { } + } +} +public static class ReflectionSupport +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() { } +} +public static class RequestBuilder +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType() { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public record RestMethodInfo : System.IEquatable +{ + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } +} +[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] +public class RestMethodParameterInfo +{ + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; init; } + public Refit.ParameterType Type { get; set; } +} +[System.Diagnostics.DebuggerDisplay("{Name}")] +public class RestMethodParameterProperty +{ + public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } +} +public static class RestServiceReflectionExtensions +{ + extension(Refit.RestService) + { + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } +} diff --git a/src/Refit.Reflection/PublicAPI/net11.0/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net11.0/PublicAPI.txt index e69de29bb..f7c81f521 100644 --- a/src/Refit.Reflection/PublicAPI/net11.0/PublicAPI.txt +++ b/src/Refit.Reflection/PublicAPI/net11.0/PublicAPI.txt @@ -0,0 +1,93 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public interface IReflectionFieldNameProvider +{ + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter +{ + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } +} +public static class ReflectionJsonSerializerOptionsExtensions +{ + extension(System.Text.Json.JsonSerializerOptions options) + { + public System.Text.Json.JsonSerializerOptions AddReflectionConverters() { } + } +} +public static class ReflectionSupport +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() { } +} +public static class RequestBuilder +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType() { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public record RestMethodInfo : System.IEquatable +{ + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } +} +[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] +public class RestMethodParameterInfo +{ + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; init; } + public Refit.ParameterType Type { get; set; } +} +[System.Diagnostics.DebuggerDisplay("{Name}")] +public class RestMethodParameterProperty +{ + public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } +} +public static class RestServiceReflectionExtensions +{ + extension(Refit.RestService) + { + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } +} diff --git a/src/Refit.Reflection/PublicAPI/net462/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net462/PublicAPI.txt index e69de29bb..f7c81f521 100644 --- a/src/Refit.Reflection/PublicAPI/net462/PublicAPI.txt +++ b/src/Refit.Reflection/PublicAPI/net462/PublicAPI.txt @@ -0,0 +1,93 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public interface IReflectionFieldNameProvider +{ + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter +{ + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } +} +public static class ReflectionJsonSerializerOptionsExtensions +{ + extension(System.Text.Json.JsonSerializerOptions options) + { + public System.Text.Json.JsonSerializerOptions AddReflectionConverters() { } + } +} +public static class ReflectionSupport +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() { } +} +public static class RequestBuilder +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType() { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public record RestMethodInfo : System.IEquatable +{ + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } +} +[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] +public class RestMethodParameterInfo +{ + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; init; } + public Refit.ParameterType Type { get; set; } +} +[System.Diagnostics.DebuggerDisplay("{Name}")] +public class RestMethodParameterProperty +{ + public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } +} +public static class RestServiceReflectionExtensions +{ + extension(Refit.RestService) + { + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } +} diff --git a/src/Refit.Reflection/PublicAPI/net470/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net470/PublicAPI.txt index e69de29bb..f7c81f521 100644 --- a/src/Refit.Reflection/PublicAPI/net470/PublicAPI.txt +++ b/src/Refit.Reflection/PublicAPI/net470/PublicAPI.txt @@ -0,0 +1,93 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public interface IReflectionFieldNameProvider +{ + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter +{ + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } +} +public static class ReflectionJsonSerializerOptionsExtensions +{ + extension(System.Text.Json.JsonSerializerOptions options) + { + public System.Text.Json.JsonSerializerOptions AddReflectionConverters() { } + } +} +public static class ReflectionSupport +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() { } +} +public static class RequestBuilder +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType() { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public record RestMethodInfo : System.IEquatable +{ + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } +} +[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] +public class RestMethodParameterInfo +{ + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; init; } + public Refit.ParameterType Type { get; set; } +} +[System.Diagnostics.DebuggerDisplay("{Name}")] +public class RestMethodParameterProperty +{ + public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } +} +public static class RestServiceReflectionExtensions +{ + extension(Refit.RestService) + { + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } +} diff --git a/src/Refit.Reflection/PublicAPI/net471/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net471/PublicAPI.txt index e69de29bb..f7c81f521 100644 --- a/src/Refit.Reflection/PublicAPI/net471/PublicAPI.txt +++ b/src/Refit.Reflection/PublicAPI/net471/PublicAPI.txt @@ -0,0 +1,93 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public interface IReflectionFieldNameProvider +{ + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter +{ + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } +} +public static class ReflectionJsonSerializerOptionsExtensions +{ + extension(System.Text.Json.JsonSerializerOptions options) + { + public System.Text.Json.JsonSerializerOptions AddReflectionConverters() { } + } +} +public static class ReflectionSupport +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() { } +} +public static class RequestBuilder +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType() { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public record RestMethodInfo : System.IEquatable +{ + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } +} +[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] +public class RestMethodParameterInfo +{ + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; init; } + public Refit.ParameterType Type { get; set; } +} +[System.Diagnostics.DebuggerDisplay("{Name}")] +public class RestMethodParameterProperty +{ + public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } +} +public static class RestServiceReflectionExtensions +{ + extension(Refit.RestService) + { + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } +} diff --git a/src/Refit.Reflection/PublicAPI/net472/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net472/PublicAPI.txt index e69de29bb..f7c81f521 100644 --- a/src/Refit.Reflection/PublicAPI/net472/PublicAPI.txt +++ b/src/Refit.Reflection/PublicAPI/net472/PublicAPI.txt @@ -0,0 +1,93 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public interface IReflectionFieldNameProvider +{ + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter +{ + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } +} +public static class ReflectionJsonSerializerOptionsExtensions +{ + extension(System.Text.Json.JsonSerializerOptions options) + { + public System.Text.Json.JsonSerializerOptions AddReflectionConverters() { } + } +} +public static class ReflectionSupport +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() { } +} +public static class RequestBuilder +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType() { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public record RestMethodInfo : System.IEquatable +{ + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } +} +[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] +public class RestMethodParameterInfo +{ + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; init; } + public Refit.ParameterType Type { get; set; } +} +[System.Diagnostics.DebuggerDisplay("{Name}")] +public class RestMethodParameterProperty +{ + public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } +} +public static class RestServiceReflectionExtensions +{ + extension(Refit.RestService) + { + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } +} diff --git a/src/Refit.Reflection/PublicAPI/net48/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net48/PublicAPI.txt index e69de29bb..f7c81f521 100644 --- a/src/Refit.Reflection/PublicAPI/net48/PublicAPI.txt +++ b/src/Refit.Reflection/PublicAPI/net48/PublicAPI.txt @@ -0,0 +1,93 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public interface IReflectionFieldNameProvider +{ + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter +{ + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } +} +public static class ReflectionJsonSerializerOptionsExtensions +{ + extension(System.Text.Json.JsonSerializerOptions options) + { + public System.Text.Json.JsonSerializerOptions AddReflectionConverters() { } + } +} +public static class ReflectionSupport +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() { } +} +public static class RequestBuilder +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType() { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public record RestMethodInfo : System.IEquatable +{ + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } +} +[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] +public class RestMethodParameterInfo +{ + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; init; } + public Refit.ParameterType Type { get; set; } +} +[System.Diagnostics.DebuggerDisplay("{Name}")] +public class RestMethodParameterProperty +{ + public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } +} +public static class RestServiceReflectionExtensions +{ + extension(Refit.RestService) + { + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } +} diff --git a/src/Refit.Reflection/PublicAPI/net481/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net481/PublicAPI.txt index e69de29bb..f7c81f521 100644 --- a/src/Refit.Reflection/PublicAPI/net481/PublicAPI.txt +++ b/src/Refit.Reflection/PublicAPI/net481/PublicAPI.txt @@ -0,0 +1,93 @@ +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Benchmarks")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection.Tests")] +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] +namespace Refit; + +public interface IReflectionFieldNameProvider +{ + string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter +{ + public ObjectToInferredTypesConverter() { } + public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } + public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } +} +public static class ReflectionJsonSerializerOptionsExtensions +{ + extension(System.Text.Json.JsonSerializerOptions options) + { + public System.Text.Json.JsonSerializerOptions AddReflectionConverters() { } + } +} +public static class ReflectionSupport +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() { } +} +public static class RequestBuilder +{ + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType() { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } +} +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public record RestMethodInfo : System.IEquatable +{ + public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } + public System.Type HostingType { get; init; } + public System.Reflection.MethodInfo MethodInfo { get; init; } + public string Name { get; init; } + public string RelativePath { get; init; } + public System.Type ReturnType { get; init; } +} +[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] +public class RestMethodParameterInfo +{ + public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } + public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } + public bool IsObjectPropertyParameter { get; set; } + public string? Name { get; set; } + public System.Reflection.ParameterInfo ParameterInfo { get; set; } + public System.Collections.Generic.List ParameterProperties { get; init; } + public Refit.ParameterType Type { get; set; } +} +[System.Diagnostics.DebuggerDisplay("{Name}")] +public class RestMethodParameterProperty +{ + public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } + public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } + public string Name { get; set; } + public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } + public System.Reflection.PropertyInfo PropertyInfo { get; set; } +} +public static class RestServiceReflectionExtensions +{ + extension(Refit.RestService) + { + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(System.Net.Http.HttpClient client) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl) { } + public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } + public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] + public static T For(string hostUrl, Refit.RefitSettings? settings) { } + } +} diff --git a/src/Refit.Reflection/PublicAPI/net8.0/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net8.0/PublicAPI.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/Refit.Reflection/PublicAPI/net9.0/PublicAPI.txt b/src/Refit.Reflection/PublicAPI/net9.0/PublicAPI.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/Refit.Reflection/Refit.Reflection.csproj b/src/Refit.Reflection/Refit.Reflection.csproj index ffc5a192d..e5bc62d6c 100644 --- a/src/Refit.Reflection/Refit.Reflection.csproj +++ b/src/Refit.Reflection/Refit.Reflection.csproj @@ -14,15 +14,11 @@ + + - - - - - @@ -30,10 +26,10 @@ - true - link - true - true + false + false + false + false diff --git a/src/Refit.Reflection/ReflectionJsonSerializerOptionsExtensions.cs b/src/Refit.Reflection/ReflectionJsonSerializerOptionsExtensions.cs new file mode 100644 index 000000000..144dbc9d1 --- /dev/null +++ b/src/Refit.Reflection/ReflectionJsonSerializerOptionsExtensions.cs @@ -0,0 +1,35 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Refit; + +/// Opt-in converters for that Refit's core assembly does not add, because converters disable the System.Text.Json source-generated fast-path. +public static class ReflectionJsonSerializerOptionsExtensions +{ + /// Extensions on the JSON serializer options being configured. + /// The options to add the converters to. + extension(JsonSerializerOptions options) + { + /// + /// Adds and a camelCase , + /// so values read as CLR primitives and enums are written and read as camelCase names. + /// + /// The same options instance. + /// + /// Using these options disables the System.Text.Json fast-path. Prefer UseStringEnumConverter on a + /// source-generated where a context is available. + /// + public JsonSerializerOptions AddReflectionConverters() + { + ArgumentExceptionHelper.ThrowIfNull(options); + + options.Converters.Add(new ObjectToInferredTypesConverter()); + options.Converters.Add(new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)); + return options; + } + } +} diff --git a/src/Refit/ReflectionPropertyHelpers.cs b/src/Refit.Reflection/ReflectionPropertyHelpers.cs similarity index 100% rename from src/Refit/ReflectionPropertyHelpers.cs rename to src/Refit.Reflection/ReflectionPropertyHelpers.cs diff --git a/src/Refit.Reflection/ReflectionSupport.cs b/src/Refit.Reflection/ReflectionSupport.cs new file mode 100644 index 000000000..cd0cd9410 --- /dev/null +++ b/src/Refit.Reflection/ReflectionSupport.cs @@ -0,0 +1,55 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Runtime.CompilerServices; +using System.Text.Json.Serialization.Metadata; + +namespace Refit; + +/// Registers the reflection support that core Refit calls when a generated client meets a value only reflection can handle. +public static class ReflectionSupport +{ + /// + /// Registers the reflection-based flattening of nested form values with core Refit. It is safe to call more than + /// once, and every reflection entry point in the Refit.Reflection packages calls it. Call it yourself when a + /// generated client posts a nested or run-time-typed form body and nothing else loads this package. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void EnsureRegistered() + { + ReflectionHooks.FormObjectFlattener ??= new FormObjectFlattener(); + ReflectionHooks.EnumMemberValueResolver ??= EnumMemberValues.GetEnumMemberValue; + ReflectionHooks.DefaultJsonResolverFactory ??= static () => new DefaultJsonTypeInfoResolver(); + ReflectionHooks.ReflectionResolverTest ??= static resolver => resolver is DefaultJsonTypeInfoResolver; + ReflectionHooks.ModifierCarrier ??= CarryModifiers; + } + + /// Applies the contract modifiers of reflection resolvers to another resolver, so registrations such as polymorphism survive. + /// The resolver that receives the modifiers. + /// The reflection resolvers whose modifiers are carried over. + /// The resolver with every modifier applied. + internal static IJsonTypeInfoResolver CarryModifiers(IJsonTypeInfoResolver resolver, List reflective) + { + foreach (var reflectionResolver in reflective) + { + foreach (var modifier in ((DefaultJsonTypeInfoResolver)reflectionResolver).Modifiers) + { + resolver = resolver.WithAddedModifier(modifier); + } + } + + return resolver; + } + + /// Creates a form map for a source object, registering the reflection support first. + /// The source object or dictionary to convert into form entries. + /// The Refit settings controlling formatting. + /// The created form map. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static FormValueMultimap CreateFormMap(object source, RefitSettings settings) + { + EnsureRegistered(); + return new(source, settings); + } +} diff --git a/src/Refit.Reflection/RequestBuilder.cs b/src/Refit.Reflection/RequestBuilder.cs new file mode 100644 index 000000000..189c9113b --- /dev/null +++ b/src/Refit.Reflection/RequestBuilder.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace Refit; + +/// +/// Provides static methods for creating request builders for Refit interface types. This class enables the +/// generation of strongly-typed HTTP client implementations based on interface definitions and optional settings. +/// +/// Request builders generated by this class use reflection to analyze the provided interface +/// type and create implementations for HTTP API calls. All members of this class are thread-safe and can be used +/// concurrently across multiple threads. +public static class RequestBuilder +{ + /// Creates an HTTP request builder for the specified interface type. + /// The interface type that defines the HTTP API methods to be implemented by the request builder. + /// The Refit settings to use for configuring the request builder. May be null to use default settings. + /// An instance of IRequestBuilder T that can be used to construct HTTP requests for the specified interface type. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "Type parameter intentionally specified explicitly by callers.")] + public static IRequestBuilder ForType(RefitSettings? settings) => + RequestBuilderFactory.Create(settings); + + /// Creates a request builder for the specified type, enabling construction of requests against its members. + /// The type for which to create the request builder. + /// An object that can be used to build requests for the specified type. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "Type parameter intentionally specified explicitly by callers.")] + public static IRequestBuilder ForType() => RequestBuilderFactory.Create(null); + + /// Creates a request builder for the specified Refit interface. + /// The interface type that defines the HTTP API contract, including a closed generic interface, decorated with Refit attributes. + /// Optional settings to customize the behavior of the generated request builder. If null, default settings are used. + /// An IRequestBuilder instance that can be used to construct HTTP requests for the specified interface. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IRequestBuilder ForType(Type refitInterfaceType, RefitSettings? settings) => + RequestBuilderFactory.Create(refitInterfaceType, settings); + + /// Creates a request builder for the specified Refit interface type. + /// The interface type that defines the Refit API contract, including a closed generic interface, decorated with Refit attributes. + /// An IRequestBuilder instance that can be used to construct HTTP requests for the specified interface type. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static IRequestBuilder ForType(Type refitInterfaceType) => ForType(refitInterfaceType, null); +} diff --git a/src/Refit.Reflection/RequestBuilderFactory.cs b/src/Refit.Reflection/RequestBuilderFactory.cs index 74650095e..463ee6190 100644 --- a/src/Refit.Reflection/RequestBuilderFactory.cs +++ b/src/Refit.Reflection/RequestBuilderFactory.cs @@ -1,40 +1,40 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. + using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Refit; -/// Default implementation of IRequestBuilderFactory. -internal class RequestBuilderFactory : IRequestBuilderFactory +/// Creates the reflection request builders. +internal static class RequestBuilderFactory { - /// + /// Creates a strongly typed request builder for the specified interface type. + /// The Refit interface type. + /// The settings to configure the builder. + /// A request builder for the interface type. [MethodImpl(MethodImplOptions.AggressiveInlining)] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Type parameter intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - public IRequestBuilder Create< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(RefitSettings? settings) => - new CachedRequestBuilderImplementation( + internal static IRequestBuilder Create(RefitSettings? settings) + { + ReflectionSupport.EnsureRegistered(); + return new CachedRequestBuilderImplementation( new RequestBuilderImplementation(settings)); + } - /// + /// Creates a request builder for the specified interface type. + /// The Refit interface type. + /// The settings to configure the builder. + /// A request builder for the interface type. [MethodImpl(MethodImplOptions.AggressiveInlining)] - [RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - public IRequestBuilder Create( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - RefitSettings? settings) => - new CachedRequestBuilderImplementation( + internal static IRequestBuilder Create(Type refitInterfaceType, RefitSettings? settings) + { + ReflectionSupport.EnsureRegistered(); + return new CachedRequestBuilderImplementation( new RequestBuilderImplementation(refitInterfaceType, settings)); + } } diff --git a/src/Refit.Reflection/RequestBuilderImplementation.Payload.cs b/src/Refit.Reflection/RequestBuilderImplementation.Payload.cs index 52f35a136..3d24c0945 100644 --- a/src/Refit.Reflection/RequestBuilderImplementation.Payload.cs +++ b/src/Refit.Reflection/RequestBuilderImplementation.Payload.cs @@ -70,7 +70,7 @@ internal void SelectBodyContent(RestMethodInfoInternal restMethod, object param, StringHelpers.EscapeDataString(str), Encoding.UTF8, "application/x-www-form-urlencoded") - : new FormUrlEncodedContent(new FormValueMultimap(param, _settings)); + : new FormUrlEncodedContent(ReflectionSupport.CreateFormMap(param, _settings)); break; } @@ -272,11 +272,11 @@ internal void AddMultiPart( /// flattening. Each entry is added as its own text under the resolved field name. internal void AddFlattenedFormObject(MultipartFormDataContent multiPartContent, object param) { - foreach (var field in new FormValueMultimap(param, _settings)) + foreach (var field in ReflectionSupport.CreateFormMap(param, _settings)) { // A field with no resolvable name cannot be a valid form-data part (the framework rejects an empty // content-disposition name), so it is skipped rather than allowed to throw mid-request. - if (field.Key is null || string.IsNullOrWhiteSpace(field.Key)) + if (string.IsNullOrWhiteSpace(field.Key)) { continue; } @@ -486,7 +486,7 @@ internal void AppendIndexedCollectionParameters( var valueType = kvp.Value?.GetType() ?? typeof(object); queryParamsToAdd.Add(new( indexedKey + attr.Delimiter + kvp.Key, - GeneratedRequestRunner.FormatUrlParameter(_settings, kvp.Value, valueType, valueType), + GeneratedRequestRunner.FormatUrlParameter(_settings, kvp.Value, GetCachedAttributeProvider(valueType), valueType), KeyPreEscaped: true)); } diff --git a/src/Refit.Reflection/RequestBuilderImplementation.QueryAndHeaders.cs b/src/Refit.Reflection/RequestBuilderImplementation.QueryAndHeaders.cs index aea7d4a7a..e195a33d9 100644 --- a/src/Refit.Reflection/RequestBuilderImplementation.QueryAndHeaders.cs +++ b/src/Refit.Reflection/RequestBuilderImplementation.QueryAndHeaders.cs @@ -340,7 +340,7 @@ internal static QueryPropertyMetadata[] GetCachedQueryProperties(Type type) => /// The underlying attribute provider. /// The cached attribute provider. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static ICustomAttributeProvider GetCachedAttributeProvider(ICustomAttributeProvider provider) => + internal static IParameterAttributeProvider GetCachedAttributeProvider(ICustomAttributeProvider provider) => AttributeProviderCache.GetValue(provider, static p => new CachedAttributeProvider(p)); /// Builds the per-type query-property metadata, reading each property's serialization-ignore, query and @@ -511,7 +511,7 @@ internal List BuildQueryMap( var keyType = key.GetType(); var formattedKey = GeneratedRequestRunner.FormatUrlParameter(_settings, key, GetCachedAttributeProvider(keyType), keyType); - if (formattedKey is null || string.IsNullOrWhiteSpace(formattedKey)) // blank keys can't be put in the query string + if (string.IsNullOrWhiteSpace(formattedKey)) // blank keys can't be put in the query string { continue; } @@ -609,7 +609,7 @@ internal string BuildPropertyQueryKey(PropertyInfo propertyInfo, AliasAsAttribut var name = aliasAttribute?.Name ?? queryAttribute?.Name ?? (_settings.HonorContentSerializerPropertyNamesInQuery - ? _settings.ContentSerializer.GetFieldNameForProperty(propertyInfo) + ? SerializerFieldNames.Resolve(_settings.ContentSerializer, propertyInfo) : null) ?? _settings.UrlParameterKeyFormatter.Format(propertyInfo.Name); diff --git a/src/Refit.Reflection/RequestBuilderImplementation.RequestBuilding.cs b/src/Refit.Reflection/RequestBuilderImplementation.RequestBuilding.cs index 67fe020fd..22692741d 100644 --- a/src/Refit.Reflection/RequestBuilderImplementation.RequestBuilding.cs +++ b/src/Refit.Reflection/RequestBuilderImplementation.RequestBuilding.cs @@ -637,7 +637,7 @@ internal void AppendObjectPropertyFragment( var formatted = GeneratedRequestRunner.FormatUrlParameter( _settings, propertyObject, - property.PropertyInfo, + GetCachedAttributeProvider(property.PropertyInfo), property.PropertyInfo.PropertyType); // An optional {param.Prop?} placeholder whose bound value formats to nothing drops the segment and the '/' @@ -685,7 +685,7 @@ internal void AppendDynamicRouteFragment( GeneratedRequestRunner.FormatUrlParameter( _settings, paramValue, - parameterInfo, + GetCachedAttributeProvider(parameterInfo), parameterInfo.ParameterType) ?? string.Empty)); return; } @@ -709,7 +709,7 @@ internal void AppendDynamicRouteFragment( GeneratedRequestRunner.FormatUrlParameter( _settings, section, - parameterInfo, + GetCachedAttributeProvider(parameterInfo), parameterInfo.ParameterType) ?? string.Empty)); sectionStart = i + 1; } @@ -726,7 +726,7 @@ internal void AppendNormalRouteFragment( ParameterInfo parameterInfo, bool isOptional) { - var formatted = GeneratedRequestRunner.FormatUrlParameter(_settings, param, parameterInfo, parameterInfo.ParameterType); + var formatted = GeneratedRequestRunner.FormatUrlParameter(_settings, param, GetCachedAttributeProvider(parameterInfo), parameterInfo.ParameterType); // An optional {name?} placeholder whose bound value formats to nothing (a null argument by default) drops the // segment and the '/' before it, so the URL never gains a trailing or doubled slash. diff --git a/src/Refit.Reflection/RequestBuilderImplementation.cs b/src/Refit.Reflection/RequestBuilderImplementation.cs index abc15d566..2b41fcde9 100644 --- a/src/Refit.Reflection/RequestBuilderImplementation.cs +++ b/src/Refit.Reflection/RequestBuilderImplementation.cs @@ -73,6 +73,7 @@ internal RequestBuilderImplementation( var targetInterfaceInheritedInterfaces = refitInterfaceType.GetInterfaces(); + ReflectionSupport.EnsureRegistered(); _settings = refitSettings ?? new RefitSettings(); _serializer = _settings.ContentSerializer; _interfaceGenericHttpMethods = diff --git a/src/Refit/RestMethodInfo.cs b/src/Refit.Reflection/RestMethodInfo.cs similarity index 100% rename from src/Refit/RestMethodInfo.cs rename to src/Refit.Reflection/RestMethodInfo.cs diff --git a/src/Refit/RestMethodParameterInfo.cs b/src/Refit.Reflection/RestMethodParameterInfo.cs similarity index 100% rename from src/Refit/RestMethodParameterInfo.cs rename to src/Refit.Reflection/RestMethodParameterInfo.cs diff --git a/src/Refit/RestMethodParameterProperty.cs b/src/Refit.Reflection/RestMethodParameterProperty.cs similarity index 100% rename from src/Refit/RestMethodParameterProperty.cs rename to src/Refit.Reflection/RestMethodParameterProperty.cs diff --git a/src/Refit.Reflection/RestServiceReflectionExtensions.cs b/src/Refit.Reflection/RestServiceReflectionExtensions.cs new file mode 100644 index 000000000..3235f2285 --- /dev/null +++ b/src/Refit.Reflection/RestServiceReflectionExtensions.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace Refit; + +/// Adds the reflection-backed client creation methods to . +public static class RestServiceReflectionExtensions +{ + /// Caches the resolved generated implementation type per interface. + private static readonly ConcurrentDictionary _typeMapping = new(); + + /// Extension members of that use reflection when a client cannot be generated inline. + extension(RestService) + { + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// The the implementation will use to send requests. + /// to use to build requests. + /// An instance that implements . + public static T For(HttpClient client, IRequestBuilder builder) => (T)RestService.For(typeof(T), client, builder); + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// The the implementation will use to send requests. + /// to use to configure the HttpClient. + /// An instance that implements . + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "Type parameter intentionally specified explicitly by callers.")] + public static T For(HttpClient client, RefitSettings? settings) + { + var resolvedSettings = settings ?? new(); + ReflectionSupport.EnsureRegistered(); + + // A generated settings factory means every method builds its request inline, so the reflection + // request builder is never needed for this interface. + return RestService.TryResolveInlineClient(client, resolvedSettings, RestService._generatedRegistrationRunner, out var instance) + ? instance + : RestService.For(client, RequestBuilder.ForType(settings)); + } + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// The the implementation will use to send requests. + /// An instance that implements . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "Type parameter intentionally specified explicitly by callers.")] + public static T For(HttpClient client) => RestService.For(client, (RefitSettings?)null); + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// Base address the implementation will use. + /// to use to configure the HttpClient. + /// An instance that implements . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "Type parameter intentionally specified explicitly by callers.")] + public static T For(string hostUrl, RefitSettings? settings) => + RestService.For(RestService.CreateHttpClient(hostUrl, settings), settings); + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// Base address the implementation will use. + /// An instance that implements . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [SuppressMessage( + "Design", + "SST2307:Generic method type parameters should be inferable from the parameters", + Justification = "Type parameter intentionally specified explicitly by callers.")] + public static T For(string hostUrl) => RestService.For(hostUrl, null); + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// The the implementation will use to send requests. + /// to use to build requests. + /// An instance that implements . + public static object For(Type refitInterfaceType, HttpClient client, IRequestBuilder builder) + { + if (RestService._generatedFactories.TryGetValue(refitInterfaceType, out var factory)) + { + return factory(client, builder); + } + + var generatedType = _typeMapping.GetOrAdd(refitInterfaceType, GeneratedTypeResolver.Resolve); + + return Activator.CreateInstance(generatedType, client, builder)!; + } + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// The the implementation will use to send requests. + /// to use to configure the HttpClient. + /// An instance that implements . + public static object For(Type refitInterfaceType, HttpClient client, RefitSettings? settings) + { + var resolvedSettings = settings ?? new(); + ReflectionSupport.EnsureRegistered(); + + // A generated settings factory means every method builds its request inline, so the reflection + // request builder is never needed for this interface. + return RestService.TryResolveInlineClient(refitInterfaceType, client, resolvedSettings, RestService._generatedRegistrationRunner, out var instance) + ? instance + : RestService.For(refitInterfaceType, client, RequestBuilder.ForType(refitInterfaceType, settings)); + } + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// The the implementation will use to send requests. + /// An instance that implements . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static object For(Type refitInterfaceType, HttpClient client) => + RestService.For(refitInterfaceType, client, (RefitSettings?)null); + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// Base address the implementation will use. + /// to use to configure the HttpClient. + /// An instance that implements . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static object For(Type refitInterfaceType, string hostUrl, RefitSettings? settings) => + RestService.For(refitInterfaceType, RestService.CreateHttpClient(hostUrl, settings), settings); + + /// Generate a Refit implementation of the specified interface. + /// Interface to create the implementation for. + /// Base address the implementation will use. + /// An instance that implements . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static object For(Type refitInterfaceType, string hostUrl) => + RestService.For(refitInterfaceType, hostUrl, null); + } +} diff --git a/src/Refit.Reflection/SerializerFieldNames.cs b/src/Refit.Reflection/SerializerFieldNames.cs new file mode 100644 index 000000000..8bac080d7 --- /dev/null +++ b/src/Refit.Reflection/SerializerFieldNames.cs @@ -0,0 +1,66 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Reflection; +using System.Text.Json.Serialization; +using System.Xml.Serialization; + +namespace Refit; + +/// Resolves the field name a content serializer gives a property, by reading the attributes its name style uses. +internal static class SerializerFieldNames +{ + /// The full name of Newtonsoft.Json's property-name attribute, matched by name so this package needs no Newtonsoft reference. + private const string NewtonsoftAttributeName = "Newtonsoft.Json.JsonPropertyAttribute"; + + /// Resolves the serializer-specific field name for a property. + /// The configured content serializer. + /// The property to name. + /// The serializer's name for the property, or when it has none. + internal static string? Resolve(IHttpContentSerializer serializer, PropertyInfo property) + { + ArgumentExceptionHelper.ThrowIfNull(property); + + if (serializer is IReflectionFieldNameProvider provider) + { + return provider.GetFieldNameForProperty(property); + } + + return serializer is IContentSerializerNameStyle style + ? ResolveForStyle(style.NameStyle, property) + : null; + } + + /// Resolves the field name for one attribute family. + /// The attribute family. + /// The property to name. + /// The name, or . + internal static string? ResolveForStyle(ContentSerializerNameStyle nameStyle, PropertyInfo property) => + nameStyle switch + { + ContentSerializerNameStyle.Newtonsoft => ReadNewtonsoftName(property), + ContentSerializerNameStyle.Xml => property.GetCustomAttribute(true)?.ElementName + ?? property.GetCustomAttribute(true)?.AttributeName, + _ => property.GetCustomAttribute(true)?.Name, + }; + + /// Reads the PropertyName of a Newtonsoft.Json [JsonProperty] attribute by its type name. + /// The property to inspect. + /// The attribute's property name, or . + internal static string? ReadNewtonsoftName(PropertyInfo property) + { + foreach (var attribute in property.GetCustomAttributes(true)) + { + for (var type = attribute.GetType(); type is not null; type = type.BaseType) + { + if (type.FullName == NewtonsoftAttributeName) + { + return (string?)type.GetProperty("PropertyName")!.GetValue(attribute); + } + } + } + + return null; + } +} diff --git a/src/Refit.Reflection/targets/Refit.Reflection.targets b/src/Refit.Reflection/targets/Refit.Reflection.targets deleted file mode 100644 index e960af745..000000000 --- a/src/Refit.Reflection/targets/Refit.Reflection.targets +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/src/Refit.Testing/PublicAPI/net10.0/PublicAPI.txt b/src/Refit.Testing/PublicAPI/net10.0/PublicAPI.txt index 181223d3b..da1c38bb6 100644 --- a/src/Refit.Testing/PublicAPI/net10.0/PublicAPI.txt +++ b/src/Refit.Testing/PublicAPI/net10.0/PublicAPI.txt @@ -141,10 +141,8 @@ public sealed class StubHttp : System.Net.Http.HttpMessageHandler, System.Collec public System.Collections.Generic.IReadOnlyList Requests { get; } public System.TimeProvider TimeProvider { get; set; } public void Add(Refit.Testing.RouteMatcher route, Refit.Testing.StubResponse response) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T CreateClient(string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T CreateClient(string hostUrl, Refit.RefitSettings baseSettings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] diff --git a/src/Refit.Testing/PublicAPI/net11.0/PublicAPI.txt b/src/Refit.Testing/PublicAPI/net11.0/PublicAPI.txt index 181223d3b..da1c38bb6 100644 --- a/src/Refit.Testing/PublicAPI/net11.0/PublicAPI.txt +++ b/src/Refit.Testing/PublicAPI/net11.0/PublicAPI.txt @@ -141,10 +141,8 @@ public sealed class StubHttp : System.Net.Http.HttpMessageHandler, System.Collec public System.Collections.Generic.IReadOnlyList Requests { get; } public System.TimeProvider TimeProvider { get; set; } public void Add(Refit.Testing.RouteMatcher route, Refit.Testing.StubResponse response) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T CreateClient(string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T CreateClient(string hostUrl, Refit.RefitSettings baseSettings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] diff --git a/src/Refit.Testing/PublicAPI/net8.0/PublicAPI.txt b/src/Refit.Testing/PublicAPI/net8.0/PublicAPI.txt deleted file mode 100644 index 181223d3b..000000000 --- a/src/Refit.Testing/PublicAPI/net8.0/PublicAPI.txt +++ /dev/null @@ -1,184 +0,0 @@ -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Testing.Tests")] -namespace Refit.Testing; - -[System.Diagnostics.DebuggerDisplay("{Delay}")] -public sealed class NetworkBehavior -{ - public NetworkBehavior() { } - public NetworkBehavior(int seed) { } - public System.TimeSpan Delay { get; set; } - public double ErrorPercent { get; set; } - public System.Net.HttpStatusCode ErrorStatusCode { get; set; } - public System.Func FailureFactory { get; set; } - public double FailurePercent { get; set; } - public double Variance { get; set; } - public System.Net.Http.HttpResponseMessage CreateErrorResponse() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Exception CreateFailure() { } - public System.TimeSpan NextDelay() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public bool NextIsError() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public bool NextIsFailure() { } -} -public static class Reply -{ - public static Refit.Testing.StubResponse Content(System.Net.Http.HttpContent body) { } - public static Refit.Testing.StubResponse From(System.Func responder) { } - public static Refit.Testing.StubResponse From(System.Func> responder) { } - public static Refit.Testing.StubResponse From(System.Func> responder) { } - public static Refit.Testing.StubResponse Json(string body) { } - public static Refit.Testing.StubResponse Json(string body, System.Net.HttpStatusCode status) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse JsonLines(System.Collections.Generic.IEnumerable items) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse ServerSentEvents(System.Collections.Generic.IEnumerable items) { } - public static Refit.Testing.StubResponse Status(System.Net.HttpStatusCode statusCode) { } - public static Refit.Testing.StubResponse Stream(Refit.Testing.StreamSource source) { } - public static Refit.Testing.StubResponse Text(string body) { } - public static Refit.Testing.StubResponse Text(string body, string contentType) { } - public static Refit.Testing.StubResponse With(T body) { } - public static Refit.Testing.StubResponse With(T body, System.Net.HttpStatusCode status) { } -} -[System.Diagnostics.DebuggerDisplay("Enabled = {IsEnabled}, MaxBytes = {MaxBytes}")] -public sealed class RequestCapture -{ - public bool IsEnabled { get; } - public int? MaxBytes { get; } - public static Refit.Testing.RequestCapture Full { get; } - public static Refit.Testing.RequestCapture None { get; } - public static Refit.Testing.RequestCapture Bounded(int maxBytes) { } -} -public static class RetryReply -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse After(System.DateTimeOffset date) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse After(System.TimeSpan delay) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse After(System.DateTimeOffset date, System.Net.HttpStatusCode status) { } - public static Refit.Testing.StubResponse After(System.TimeSpan delay, System.Net.HttpStatusCode status) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse Header(string name, string value) { } - public static Refit.Testing.StubResponse Header(string name, string value, System.Net.HttpStatusCode status) { } -} -public static class Route -{ - public static Refit.Testing.RouteMatcher Any(string template) { } - public static Refit.Testing.RouteMatcher Delete(string template) { } - public static Refit.Testing.RouteMatcher Fallback() { } - public static Refit.Testing.RouteMatcher For(System.Net.Http.HttpMethod method, string template) { } - public static Refit.Testing.RouteMatcher Get(string template) { } - public static Refit.Testing.RouteMatcher Head(string template) { } - public static Refit.Testing.RouteMatcher Patch(string template) { } - public static Refit.Testing.RouteMatcher Post(string template) { } - public static Refit.Testing.RouteMatcher Put(string template) { } -} -[System.Diagnostics.DebuggerDisplay("RouteMatcher: {Method}")] -public sealed class RouteMatcher -{ - public RouteMatcher() { } - public string? Body { get; init; } - public string? ExactQuery { get; init; } - public (string Key, string Value)[]? ExactQueryParams { get; init; } - public bool Fallback { get; init; } - public (string Key, string Value)[]? FormData { get; init; } - public (string Name, string Value)[]? Headers { get; init; } - public System.Net.Http.HttpMethod? Method { get; init; } - public (string Key, string Value)[]? Query { get; init; } - public bool Reusable { get; init; } - public required string Template { get; init; } - public System.Func? Where { get; init; } - public System.Func>? WhereAsync { get; init; } -} -[System.Diagnostics.DebuggerDisplay("{Format} ReleasedChunks = {ReleasedChunks}")] -public sealed class StreamSource -{ - public StreamSource() { } - public StreamSource(Refit.StreamingContentFormat format) { } - public System.Threading.Tasks.Task Closed { get; } - public Refit.StreamingContentFormat Format { get; } - public bool IsClosed { get; } - public string MediaType { get; } - public int ReadChunks { get; } - public int ReleasedChunks { get; } - public void Complete() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void Disconnect() { } - public void Fail(System.Exception error) { } - public void Release(T item) { } - public void ReleaseBytes(byte[] bytes) { } - public void ReleaseText(string text) { } -} -[System.Diagnostics.DebuggerDisplay("StubApiResponse: {StatusCode}, Content = {Content}")] -public sealed class StubApiResponse : Refit.IApiResponse -{ - public StubApiResponse() { } - public T? Content { get; init; } - public System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; init; } - public Refit.ApiExceptionBase? Error { get; init; } - public bool HasContent { get; init; } - public System.Net.Http.Headers.HttpResponseHeaders? Headers { get; init; } - public bool IsReceived { get; init; } - public bool IsSuccessStatusCode { get; init; } - public bool IsSuccessful { get; init; } - public bool IsSuccessfulWithContent { get; init; } - public string? ReasonPhrase { get; init; } - public System.Net.Http.HttpRequestMessage? RequestMessage { get; init; } - public System.Net.HttpStatusCode? StatusCode { get; init; } - public System.Version? Version { get; init; } - public void Dispose() { } - public bool HasRequestError(out Refit.ApiRequestException? error) { } - public bool HasResponseError(out Refit.ApiException? error) { } -} -[System.Diagnostics.DebuggerDisplay("{Requests}")] -public sealed class StubHttp : System.Net.Http.HttpMessageHandler, System.Collections.Generic.IEnumerable -{ - public StubHttp() { } - public StubHttp(Refit.Testing.NetworkBehavior behavior) { } - public Refit.Testing.NetworkBehavior? Behavior { get; set; } - public Refit.Testing.RequestCapture RequestCapture { get; set; } - public System.Collections.Generic.IReadOnlyList Requests { get; } - public System.TimeProvider TimeProvider { get; set; } - public void Add(Refit.Testing.RouteMatcher route, Refit.Testing.StubResponse response) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T CreateClient(string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T CreateClient(string hostUrl, Refit.RefitSettings baseSettings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T CreateGeneratedClient(string hostUrl) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T CreateGeneratedClient(string hostUrl, Refit.RefitSettings baseSettings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public Refit.HttpRetryHandler CreateRetryHandler() { } - public Refit.HttpRetryHandler CreateRetryHandler(Refit.HttpRetryOptions options) { } - public System.Threading.Tasks.Task LastRequestBodyAsync() { } - public System.Threading.Tasks.Task RequestBodyAsync(int index) { } - protected override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { } - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public Refit.RefitSettings ToSettings() { } - public Refit.RefitSettings ToSettings(Refit.RefitSettings baseSettings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void VerifyAllCalled() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Threading.Tasks.Task VerifyAllCalledAsync() { } - public System.Threading.Tasks.Task VerifyAllCalledAsync(System.TimeSpan timeout) { } -} -[System.Diagnostics.DebuggerDisplay("{Status}")] -public sealed class StubResponse -{ - public StubResponse() { } - public System.Func>? CancellableResponderAsync { get; init; } - public System.Net.Http.HttpContent? Content { get; init; } - public string? ContentType { get; init; } - public string? Json { get; init; } - public System.Func? Responder { get; init; } - public System.Func>? ResponderAsync { get; init; } - public System.Net.HttpStatusCode Status { get; init; } - public string? Text { get; init; } -} diff --git a/src/Refit.Testing/PublicAPI/net9.0/PublicAPI.txt b/src/Refit.Testing/PublicAPI/net9.0/PublicAPI.txt deleted file mode 100644 index 181223d3b..000000000 --- a/src/Refit.Testing/PublicAPI/net9.0/PublicAPI.txt +++ /dev/null @@ -1,184 +0,0 @@ -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Testing.Tests")] -namespace Refit.Testing; - -[System.Diagnostics.DebuggerDisplay("{Delay}")] -public sealed class NetworkBehavior -{ - public NetworkBehavior() { } - public NetworkBehavior(int seed) { } - public System.TimeSpan Delay { get; set; } - public double ErrorPercent { get; set; } - public System.Net.HttpStatusCode ErrorStatusCode { get; set; } - public System.Func FailureFactory { get; set; } - public double FailurePercent { get; set; } - public double Variance { get; set; } - public System.Net.Http.HttpResponseMessage CreateErrorResponse() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Exception CreateFailure() { } - public System.TimeSpan NextDelay() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public bool NextIsError() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public bool NextIsFailure() { } -} -public static class Reply -{ - public static Refit.Testing.StubResponse Content(System.Net.Http.HttpContent body) { } - public static Refit.Testing.StubResponse From(System.Func responder) { } - public static Refit.Testing.StubResponse From(System.Func> responder) { } - public static Refit.Testing.StubResponse From(System.Func> responder) { } - public static Refit.Testing.StubResponse Json(string body) { } - public static Refit.Testing.StubResponse Json(string body, System.Net.HttpStatusCode status) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse JsonLines(System.Collections.Generic.IEnumerable items) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse ServerSentEvents(System.Collections.Generic.IEnumerable items) { } - public static Refit.Testing.StubResponse Status(System.Net.HttpStatusCode statusCode) { } - public static Refit.Testing.StubResponse Stream(Refit.Testing.StreamSource source) { } - public static Refit.Testing.StubResponse Text(string body) { } - public static Refit.Testing.StubResponse Text(string body, string contentType) { } - public static Refit.Testing.StubResponse With(T body) { } - public static Refit.Testing.StubResponse With(T body, System.Net.HttpStatusCode status) { } -} -[System.Diagnostics.DebuggerDisplay("Enabled = {IsEnabled}, MaxBytes = {MaxBytes}")] -public sealed class RequestCapture -{ - public bool IsEnabled { get; } - public int? MaxBytes { get; } - public static Refit.Testing.RequestCapture Full { get; } - public static Refit.Testing.RequestCapture None { get; } - public static Refit.Testing.RequestCapture Bounded(int maxBytes) { } -} -public static class RetryReply -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse After(System.DateTimeOffset date) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse After(System.TimeSpan delay) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse After(System.DateTimeOffset date, System.Net.HttpStatusCode status) { } - public static Refit.Testing.StubResponse After(System.TimeSpan delay, System.Net.HttpStatusCode status) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.Testing.StubResponse Header(string name, string value) { } - public static Refit.Testing.StubResponse Header(string name, string value, System.Net.HttpStatusCode status) { } -} -public static class Route -{ - public static Refit.Testing.RouteMatcher Any(string template) { } - public static Refit.Testing.RouteMatcher Delete(string template) { } - public static Refit.Testing.RouteMatcher Fallback() { } - public static Refit.Testing.RouteMatcher For(System.Net.Http.HttpMethod method, string template) { } - public static Refit.Testing.RouteMatcher Get(string template) { } - public static Refit.Testing.RouteMatcher Head(string template) { } - public static Refit.Testing.RouteMatcher Patch(string template) { } - public static Refit.Testing.RouteMatcher Post(string template) { } - public static Refit.Testing.RouteMatcher Put(string template) { } -} -[System.Diagnostics.DebuggerDisplay("RouteMatcher: {Method}")] -public sealed class RouteMatcher -{ - public RouteMatcher() { } - public string? Body { get; init; } - public string? ExactQuery { get; init; } - public (string Key, string Value)[]? ExactQueryParams { get; init; } - public bool Fallback { get; init; } - public (string Key, string Value)[]? FormData { get; init; } - public (string Name, string Value)[]? Headers { get; init; } - public System.Net.Http.HttpMethod? Method { get; init; } - public (string Key, string Value)[]? Query { get; init; } - public bool Reusable { get; init; } - public required string Template { get; init; } - public System.Func? Where { get; init; } - public System.Func>? WhereAsync { get; init; } -} -[System.Diagnostics.DebuggerDisplay("{Format} ReleasedChunks = {ReleasedChunks}")] -public sealed class StreamSource -{ - public StreamSource() { } - public StreamSource(Refit.StreamingContentFormat format) { } - public System.Threading.Tasks.Task Closed { get; } - public Refit.StreamingContentFormat Format { get; } - public bool IsClosed { get; } - public string MediaType { get; } - public int ReadChunks { get; } - public int ReleasedChunks { get; } - public void Complete() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void Disconnect() { } - public void Fail(System.Exception error) { } - public void Release(T item) { } - public void ReleaseBytes(byte[] bytes) { } - public void ReleaseText(string text) { } -} -[System.Diagnostics.DebuggerDisplay("StubApiResponse: {StatusCode}, Content = {Content}")] -public sealed class StubApiResponse : Refit.IApiResponse -{ - public StubApiResponse() { } - public T? Content { get; init; } - public System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; init; } - public Refit.ApiExceptionBase? Error { get; init; } - public bool HasContent { get; init; } - public System.Net.Http.Headers.HttpResponseHeaders? Headers { get; init; } - public bool IsReceived { get; init; } - public bool IsSuccessStatusCode { get; init; } - public bool IsSuccessful { get; init; } - public bool IsSuccessfulWithContent { get; init; } - public string? ReasonPhrase { get; init; } - public System.Net.Http.HttpRequestMessage? RequestMessage { get; init; } - public System.Net.HttpStatusCode? StatusCode { get; init; } - public System.Version? Version { get; init; } - public void Dispose() { } - public bool HasRequestError(out Refit.ApiRequestException? error) { } - public bool HasResponseError(out Refit.ApiException? error) { } -} -[System.Diagnostics.DebuggerDisplay("{Requests}")] -public sealed class StubHttp : System.Net.Http.HttpMessageHandler, System.Collections.Generic.IEnumerable -{ - public StubHttp() { } - public StubHttp(Refit.Testing.NetworkBehavior behavior) { } - public Refit.Testing.NetworkBehavior? Behavior { get; set; } - public Refit.Testing.RequestCapture RequestCapture { get; set; } - public System.Collections.Generic.IReadOnlyList Requests { get; } - public System.TimeProvider TimeProvider { get; set; } - public void Add(Refit.Testing.RouteMatcher route, Refit.Testing.StubResponse response) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T CreateClient(string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T CreateClient(string hostUrl, Refit.RefitSettings baseSettings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T CreateGeneratedClient(string hostUrl) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T CreateGeneratedClient(string hostUrl, Refit.RefitSettings baseSettings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public Refit.HttpRetryHandler CreateRetryHandler() { } - public Refit.HttpRetryHandler CreateRetryHandler(Refit.HttpRetryOptions options) { } - public System.Threading.Tasks.Task LastRequestBodyAsync() { } - public System.Threading.Tasks.Task RequestBodyAsync(int index) { } - protected override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { } - System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public Refit.RefitSettings ToSettings() { } - public Refit.RefitSettings ToSettings(Refit.RefitSettings baseSettings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void VerifyAllCalled() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Threading.Tasks.Task VerifyAllCalledAsync() { } - public System.Threading.Tasks.Task VerifyAllCalledAsync(System.TimeSpan timeout) { } -} -[System.Diagnostics.DebuggerDisplay("{Status}")] -public sealed class StubResponse -{ - public StubResponse() { } - public System.Func>? CancellableResponderAsync { get; init; } - public System.Net.Http.HttpContent? Content { get; init; } - public string? ContentType { get; init; } - public string? Json { get; init; } - public System.Func? Responder { get; init; } - public System.Func>? ResponderAsync { get; init; } - public System.Net.HttpStatusCode Status { get; init; } - public string? Text { get; init; } -} diff --git a/src/Refit.Testing/Refit.Testing.csproj b/src/Refit.Testing/Refit.Testing.csproj index 95ad0d264..5df4d1b08 100644 --- a/src/Refit.Testing/Refit.Testing.csproj +++ b/src/Refit.Testing/Refit.Testing.csproj @@ -15,5 +15,6 @@ + diff --git a/src/Refit.Testing/StubHttp.cs b/src/Refit.Testing/StubHttp.cs index 7ce796dda..00f0606d4 100644 --- a/src/Refit.Testing/StubHttp.cs +++ b/src/Refit.Testing/StubHttp.cs @@ -180,13 +180,7 @@ public RefitSettings ToSettings(RefitSettings baseSettings) "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "The interface type is intentionally specified explicitly by the caller, matching RestService.For.")] - [RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] - public T CreateClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(string hostUrl) => CreateClient(hostUrl, new()); + public T CreateClient(string hostUrl) => CreateClient(hostUrl, new()); /// /// Creates a Refit implementation of whose HTTP requests are routed through this @@ -202,13 +196,13 @@ public T CreateClient< "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "The interface type is intentionally specified explicitly by the caller, matching RestService.For.")] - [RequiresUnreferencedCode("Creating a Refit client through the reflection path requires runtime type lookup and request metadata.")] - public T CreateClient< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(string hostUrl, RefitSettings baseSettings) => RestService.For(hostUrl, ToSettings(baseSettings)); + public T CreateClient(string hostUrl, RefitSettings baseSettings) + { + // Only this reflection-based entry point registers the reflection JSON support, so a trimmed or AOT host that + // creates generated clients never reaches it. + ReflectionSupport.EnsureRegistered(); + return RestService.For(hostUrl, ToSettings(baseSettings)); + } /// /// Creates a source-generated Refit implementation of whose HTTP requests are diff --git a/src/Refit.Xml/PublicAPI/net10.0/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net10.0/PublicAPI.txt index da6ef8f6d..7ad19f6c7 100644 --- a/src/Refit.Xml/PublicAPI/net10.0/PublicAPI.txt +++ b/src/Refit.Xml/PublicAPI/net10.0/PublicAPI.txt @@ -1,13 +1,13 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public class XmlContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public XmlContentSerializer() { } public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] diff --git a/src/Refit.Xml/PublicAPI/net11.0/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net11.0/PublicAPI.txt index da6ef8f6d..7ad19f6c7 100644 --- a/src/Refit.Xml/PublicAPI/net11.0/PublicAPI.txt +++ b/src/Refit.Xml/PublicAPI/net11.0/PublicAPI.txt @@ -1,13 +1,13 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public class XmlContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public XmlContentSerializer() { } public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] diff --git a/src/Refit.Xml/PublicAPI/net462/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net462/PublicAPI.txt index da6ef8f6d..7ad19f6c7 100644 --- a/src/Refit.Xml/PublicAPI/net462/PublicAPI.txt +++ b/src/Refit.Xml/PublicAPI/net462/PublicAPI.txt @@ -1,13 +1,13 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public class XmlContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public XmlContentSerializer() { } public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] diff --git a/src/Refit.Xml/PublicAPI/net470/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net470/PublicAPI.txt index da6ef8f6d..7ad19f6c7 100644 --- a/src/Refit.Xml/PublicAPI/net470/PublicAPI.txt +++ b/src/Refit.Xml/PublicAPI/net470/PublicAPI.txt @@ -1,13 +1,13 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public class XmlContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public XmlContentSerializer() { } public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] diff --git a/src/Refit.Xml/PublicAPI/net471/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net471/PublicAPI.txt index da6ef8f6d..7ad19f6c7 100644 --- a/src/Refit.Xml/PublicAPI/net471/PublicAPI.txt +++ b/src/Refit.Xml/PublicAPI/net471/PublicAPI.txt @@ -1,13 +1,13 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public class XmlContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public XmlContentSerializer() { } public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] diff --git a/src/Refit.Xml/PublicAPI/net472/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net472/PublicAPI.txt index da6ef8f6d..7ad19f6c7 100644 --- a/src/Refit.Xml/PublicAPI/net472/PublicAPI.txt +++ b/src/Refit.Xml/PublicAPI/net472/PublicAPI.txt @@ -1,13 +1,13 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public class XmlContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public XmlContentSerializer() { } public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] diff --git a/src/Refit.Xml/PublicAPI/net48/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net48/PublicAPI.txt index da6ef8f6d..7ad19f6c7 100644 --- a/src/Refit.Xml/PublicAPI/net48/PublicAPI.txt +++ b/src/Refit.Xml/PublicAPI/net48/PublicAPI.txt @@ -1,13 +1,13 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public class XmlContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public XmlContentSerializer() { } public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] diff --git a/src/Refit.Xml/PublicAPI/net481/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net481/PublicAPI.txt index da6ef8f6d..7ad19f6c7 100644 --- a/src/Refit.Xml/PublicAPI/net481/PublicAPI.txt +++ b/src/Refit.Xml/PublicAPI/net481/PublicAPI.txt @@ -1,13 +1,13 @@ namespace Refit; [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer +public class XmlContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer { public XmlContentSerializer() { } public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public T? DeserializeFromString(string content) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] diff --git a/src/Refit.Xml/PublicAPI/net8.0/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net8.0/PublicAPI.txt deleted file mode 100644 index da6ef8f6d..000000000 --- a/src/Refit.Xml/PublicAPI/net8.0/PublicAPI.txt +++ /dev/null @@ -1,33 +0,0 @@ -namespace Refit; - -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer -{ - public XmlContentSerializer() { } - public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } - public T? DeserializeFromString(string content) { } - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - public System.Net.Http.HttpContent ToHttpContent(T item) { } -} -[System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] -public class XmlContentSerializerSettings -{ - public XmlContentSerializerSettings() { } - public System.Xml.Serialization.XmlAttributeOverrides XmlAttributeOverrides { get; set; } - public string? XmlDefaultNamespace { get; set; } - public System.Xml.Serialization.XmlSerializerNamespaces XmlNamespaces { get; set; } - public Refit.XmlReaderWriterSettings XmlReaderWriterSettings { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{ReaderSettings}")] -public class XmlReaderWriterSettings -{ - public XmlReaderWriterSettings() { } - public XmlReaderWriterSettings(System.Xml.XmlReaderSettings readerSettings) { } - public XmlReaderWriterSettings(System.Xml.XmlWriterSettings writerSettings) { } - public XmlReaderWriterSettings(System.Xml.XmlReaderSettings readerSettings, System.Xml.XmlWriterSettings writerSettings) { } - [System.Obsolete("Enabling DTD processing re-opens XML External Entity (XXE) and entity-expansion attacks and is strongly discouraged. Only set this for XML from a fully trusted source.")] - public bool AllowDtdProcessing { get; set; } - public System.Xml.XmlReaderSettings ReaderSettings { get; set; } - public System.Xml.XmlWriterSettings WriterSettings { get; set; } -} diff --git a/src/Refit.Xml/PublicAPI/net9.0/PublicAPI.txt b/src/Refit.Xml/PublicAPI/net9.0/PublicAPI.txt deleted file mode 100644 index da6ef8f6d..000000000 --- a/src/Refit.Xml/PublicAPI/net9.0/PublicAPI.txt +++ /dev/null @@ -1,33 +0,0 @@ -namespace Refit; - -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : Refit.IHttpContentSerializer, Refit.ISynchronousContentDeserializer -{ - public XmlContentSerializer() { } - public XmlContentSerializer(Refit.XmlContentSerializerSettings settings) { } - public T? DeserializeFromString(string content) { } - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - public System.Net.Http.HttpContent ToHttpContent(T item) { } -} -[System.Diagnostics.DebuggerDisplay("XmlContentSerializerSettings: XmlDefaultNamespace = {XmlDefaultNamespace}")] -public class XmlContentSerializerSettings -{ - public XmlContentSerializerSettings() { } - public System.Xml.Serialization.XmlAttributeOverrides XmlAttributeOverrides { get; set; } - public string? XmlDefaultNamespace { get; set; } - public System.Xml.Serialization.XmlSerializerNamespaces XmlNamespaces { get; set; } - public Refit.XmlReaderWriterSettings XmlReaderWriterSettings { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{ReaderSettings}")] -public class XmlReaderWriterSettings -{ - public XmlReaderWriterSettings() { } - public XmlReaderWriterSettings(System.Xml.XmlReaderSettings readerSettings) { } - public XmlReaderWriterSettings(System.Xml.XmlWriterSettings writerSettings) { } - public XmlReaderWriterSettings(System.Xml.XmlReaderSettings readerSettings, System.Xml.XmlWriterSettings writerSettings) { } - [System.Obsolete("Enabling DTD processing re-opens XML External Entity (XXE) and entity-expansion attacks and is strongly discouraged. Only set this for XML from a fully trusted source.")] - public bool AllowDtdProcessing { get; set; } - public System.Xml.XmlReaderSettings ReaderSettings { get; set; } - public System.Xml.XmlWriterSettings WriterSettings { get; set; } -} diff --git a/src/Refit.Xml/Refit.Xml.csproj b/src/Refit.Xml/Refit.Xml.csproj index 449bdd076..c7a385c65 100644 --- a/src/Refit.Xml/Refit.Xml.csproj +++ b/src/Refit.Xml/Refit.Xml.csproj @@ -4,7 +4,10 @@ XML content serializer for Refit clients that send or receive XML payloads through System.Xml.Serialization.XmlSerializer. refit;rest;http;api-client;xml;xmlserializer;serializer;content-serializer $(RefitShippingTargets) - true + false + false + false + false diff --git a/src/Refit.Xml/XmlContentSerializer.cs b/src/Refit.Xml/XmlContentSerializer.cs index 254679ed4..da3cd92db 100644 --- a/src/Refit.Xml/XmlContentSerializer.cs +++ b/src/Refit.Xml/XmlContentSerializer.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for full license information. using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; -using System.Reflection; using System.Text; using System.Xml; using System.Xml.Serialization; @@ -15,16 +14,8 @@ namespace Refit; /// Initializes a new instance of the class. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class XmlContentSerializer : IHttpContentSerializer, ISynchronousContentDeserializer +public class XmlContentSerializer : IHttpContentSerializer, ISynchronousContentDeserializer, IContentSerializerNameStyle { - /// Explains why the trimming warning is suppressed for XML reflection. - private const string XmlReflectionTrimmingJustification = - "Refit's XML serialization uses System.Xml.Serialization reflection that trimming cannot statically preserve. Use the Refit source generator for trimmed/AOT apps."; - - /// Explains why the AOT warning is suppressed for XML reflection. - private const string XmlReflectionAotJustification = - "Refit's XML serialization may generate serialization assemblies at runtime. Use the Refit source generator for AOT apps."; - /// The settings controlling XML serialization. private readonly XmlContentSerializerSettings _settings; @@ -46,13 +37,14 @@ public XmlContentSerializer() { } + /// + public ContentSerializerNameStyle NameStyle => ContentSerializerNameStyle.Xml; + /// Serialize object of type to a with Xml. /// Type of the object to serialize from. /// Object to serialize. /// that contains the serialized object in Xml. /// Thrown when is . - [UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", Justification = XmlReflectionTrimmingJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", Justification = XmlReflectionAotJustification)] public HttpContent ToHttpContent(T item) { ArgumentExceptionHelper.ThrowIfNull(item); @@ -82,8 +74,6 @@ public HttpContent ToHttpContent(T item) /// HttpContent object with Xml content to deserialize. /// CancellationToken to abort the deserialization. /// The deserialized object of type . - [UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", Justification = XmlReflectionTrimmingJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", Justification = XmlReflectionAotJustification)] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", @@ -113,8 +103,6 @@ public HttpContent ToHttpContent(T item) } /// - [UnconditionalSuppressMessage("Trimming", "IL2026:RequiresUnreferencedCode", Justification = XmlReflectionTrimmingJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050:RequiresDynamicCode", Justification = XmlReflectionAotJustification)] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", @@ -138,13 +126,4 @@ public HttpContent ToHttpContent(T item) _settings.XmlReaderWriterSettings.ReaderSettings); return (T?)xmlSerializer.Deserialize(reader); } - - /// - public string? GetFieldNameForProperty(PropertyInfo propertyInfo) - { - ArgumentExceptionHelper.ThrowIfNull(propertyInfo); - - return propertyInfo.GetCustomAttribute(true)?.ElementName - ?? propertyInfo.GetCustomAttribute(true)?.AttributeName; - } } diff --git a/src/Refit.slnx b/src/Refit.slnx index 7ac796742..2127ac587 100644 --- a/src/Refit.slnx +++ b/src/Refit.slnx @@ -107,6 +107,7 @@ + diff --git a/src/Refit/ApiException.cs b/src/Refit/ApiException.cs index b9ecaff88..5fc4862fd 100644 --- a/src/Refit/ApiException.cs +++ b/src/Refit/ApiException.cs @@ -274,9 +274,7 @@ public static async Task Create( var mediaType = response.Content.Headers.ContentType?.MediaType; if (mediaType?.Equals("application/problem+json", StringComparison.OrdinalIgnoreCase) ?? false) { - exception = await ValidationApiException - .CreateAsync(exception) - .ConfigureAwait(false); + exception = ValidationApiException.Create(exception); } response.Content.Dispose(); diff --git a/src/Refit/ApiResponseExtensions.cs b/src/Refit/ApiResponseExtensions.cs index 2eaf91955..e1fad9676 100644 --- a/src/Refit/ApiResponseExtensions.cs +++ b/src/Refit/ApiResponseExtensions.cs @@ -7,6 +7,17 @@ namespace Refit; /// Convenience helpers for working with and . public static class ApiResponseExtensions { + /// Returns the response when the check passed, otherwise a faulted task carrying its captured error. + /// The response type. + /// The response being guarded. + /// Whether the response passed the check. + /// The response, or a faulted task. + internal static ValueTask EnsureResult(TResponse response, bool succeeded) + where TResponse : IApiResponse => + succeeded + ? new(response) + : new(Task.FromException(response.GetError())); + /// Success-guard helpers on the non-generic . /// The response to guard. extension(IApiResponse response) @@ -22,9 +33,7 @@ public static class ApiResponseExtensions public ValueTask EnsureSuccessStatusCodeAsync() { var checkedResponse = response ?? throw new ArgumentNullException(nameof(response)); - return checkedResponse.IsSuccessStatusCode - ? new(checkedResponse) - : new(Task.FromException(GetError(checkedResponse))); + return EnsureResult(checkedResponse, checkedResponse.IsSuccessStatusCode); } /// @@ -38,9 +47,7 @@ public ValueTask EnsureSuccessStatusCodeAsync() public ValueTask EnsureSuccessfulAsync() { var checkedResponse = response ?? throw new ArgumentNullException(nameof(response)); - return checkedResponse.IsSuccessful - ? new(checkedResponse) - : new(Task.FromException(GetError(checkedResponse))); + return EnsureResult(checkedResponse, checkedResponse.IsSuccessful); } /// Gets the target of the first Link response header entry that carries a relation, as defined by RFC 8288. @@ -78,9 +85,7 @@ public ValueTask EnsureSuccessfulAsync() public ValueTask> EnsureSuccessStatusCodeAsync() { var checkedResponse = response ?? throw new ArgumentNullException(nameof(response)); - return checkedResponse.IsSuccessStatusCode - ? new(checkedResponse) - : new(Task.FromException>(GetError(checkedResponse))); + return EnsureResult(checkedResponse, checkedResponse.IsSuccessStatusCode); } /// @@ -94,9 +99,7 @@ public ValueTask> EnsureSuccessStatusCodeAsync() public ValueTask> EnsureSuccessfulAsync() { var checkedResponse = response ?? throw new ArgumentNullException(nameof(response)); - return checkedResponse.IsSuccessful - ? new(checkedResponse) - : new(Task.FromException>(GetError(checkedResponse))); + return EnsureResult(checkedResponse, checkedResponse.IsSuccessful); } } } diff --git a/src/Refit/AsyncEnumerableObservable{T}.cs b/src/Refit/AsyncEnumerableObservable{T}.cs index 60e60daff..630341e49 100644 --- a/src/Refit/AsyncEnumerableObservable{T}.cs +++ b/src/Refit/AsyncEnumerableObservable{T}.cs @@ -64,6 +64,7 @@ public void Dispose() /// The sequence to enumerate. /// A token that is cancelled when the subscription is disposed. /// A task that completes when the sequence has been enumerated and disposed. + [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] // The compiler's rethrow edge after an awaited disposal in finally cannot be exercised or removed. private async Task PumpAsync(IAsyncEnumerable source, CancellationToken cancellationToken) { var enumerator = source.GetAsyncEnumerator(cancellationToken); diff --git a/src/Refit/CamelCaseStringEnumConverter.cs b/src/Refit/CamelCaseStringEnumConverter.cs deleted file mode 100644 index d762ab2d8..000000000 --- a/src/Refit/CamelCaseStringEnumConverter.cs +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. -// ReactiveUI and Contributors licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Diagnostics.CodeAnalysis; -using System.Reflection; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace Refit; - -/// A converter factory that serializes enum values using camelCase names. -internal sealed class CamelCaseStringEnumConverter : JsonConverterFactory -{ - /// - public override bool CanConvert(Type typeToConvert) => - (Nullable.GetUnderlyingType(typeToConvert) ?? typeToConvert).IsEnum; - - /// - [UnconditionalSuppressMessage( - "AssemblyLoadTrimming", - "IL2026:RequiresUnreferencedCode", - Justification = - "JsonConverterFactory.CreateConverter cannot carry trim annotations, but this implementation creates a converter from a runtime enum Type.")] - [UnconditionalSuppressMessage( - "AssemblyLoadTrimming", - "IL3050:RequiresDynamicCode", - Justification = - "JsonConverterFactory.CreateConverter cannot carry AOT annotations, but this implementation closes a converter over a runtime enum Type.")] - [UnconditionalSuppressMessage( - "AssemblyLoadTrimming", - "IL2070:DynamicallyAccessedMembers", - Justification = "The converter is created from a runtime enum Type and preserves enum fields on the closed converter.")] - [UnconditionalSuppressMessage( - "AssemblyLoadTrimming", - "IL2071:DynamicallyAccessedMembers", - Justification = "The converter is created from a runtime enum Type and preserves enum fields on the closed converter.")] - [UnconditionalSuppressMessage( - "AssemblyLoadTrimming", - "IL2055:MakeGenericType", - Justification = "The converter is created from a runtime enum Type and preserves enum fields on the closed converter.")] - public override JsonConverter CreateConverter(Type typeToConvert, JsonSerializerOptions options) - { - var underlyingType = Nullable.GetUnderlyingType(typeToConvert); - var openConverterType = underlyingType is null - ? typeof(EnumConverter<>) - : typeof(NullableEnumConverter<>); - var converterType = openConverterType.MakeGenericType(underlyingType ?? typeToConvert); - return (JsonConverter)Activator.CreateInstance(converterType)!; - } - - /// Gets the preferred serialized name for the given enum field. - /// The enum field to inspect. - /// The preferred serialized name. -#if NET9_0_OR_GREATER - internal static string GetPreferredSerializedName(FieldInfo field) => - field.GetCustomAttribute()?.Name ?? ToCamelCase(field.Name); -#else - internal static string GetPreferredSerializedName(FieldInfo field) => ToCamelCase(field.Name); -#endif - - /// Converts the given value to camelCase. - /// The value to convert. - /// The camelCase form of the value. - internal static string ToCamelCase(string value) => - string.IsNullOrEmpty(value) || !char.IsUpper(value[0]) - ? value -#if NET8_0_OR_GREATER - - // Produce the camelCase form in a single allocation: copy the source, then lowercase the first character - // in place. The "char.ToLowerInvariant(value[0]) + value[1..]" form allocates an extra substring tail. - : string.Create(value.Length, value, static (span, source) => - { - source.AsSpan().CopyTo(span); - span[0] = char.ToLowerInvariant(source[0]); - }); -#else - : char.ToLowerInvariant(value[0]) + value[1..]; -#endif - - /// Determines whether the reader is positioned on a JSON null or an empty/whitespace string. - /// The reader to inspect. - /// when the value should be treated as null. - internal static bool IsNullOrEmptyString(ref Utf8JsonReader reader) => - reader.TokenType == JsonTokenType.Null - || (reader.TokenType is JsonTokenType.String or JsonTokenType.PropertyName - && string.IsNullOrWhiteSpace(reader.GetString())); - - /// A strongly-typed JSON converter that maps enum values to and from their camelCase names. - /// The enum type whose fields are inspected. - internal sealed class EnumConverter< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TEnum> : JsonConverter - where TEnum : struct, Enum - { - /// The upper bound of serialized names per enum field: its camelCase name plus its declared name. - private const int MaxNamesPerField = 2; - - /// Maps serialized names to enum values using ordinal comparison. - private readonly Dictionary _namesToValues; - - /// Maps serialized names to enum values using case-insensitive comparison. - private readonly Dictionary _namesToValuesIgnoreCase; - - /// Maps enum values to their preferred serialized names. - private readonly Dictionary _valuesToNames; - - /// Initializes a new instance of the class, building the three - /// serialized-name maps from a single scan of the enum's fields. - /// Public because the converter factory instantiates it through , - /// which resolves only a public parameterless constructor. - public EnumConverter() => - (_namesToValues, _namesToValuesIgnoreCase, _valuesToNames) = BuildNameMaps(); - - /// Gets the number of names-to-values entries, exposed so a benchmark can force and observe the - /// converter's one-time name-map construction. - internal int MapEntryCount => _namesToValues.Count; - - /// - public override TEnum Read( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) => - ReadValue(ref reader); - - /// - public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options) - { - if (_valuesToNames.TryGetValue(value, out var name)) - { - writer.WriteStringValue(name); - return; - } - - EnumHelpers.Info.WriteJsonNumericValue(writer, value); - } - - /// - public override TEnum ReadAsPropertyName( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) => - Read(ref reader, typeToConvert, options); - - /// - public override void WriteAsPropertyName( - Utf8JsonWriter writer, - TEnum value, - JsonSerializerOptions options) - { - if (_valuesToNames.TryGetValue(value, out var name)) - { - writer.WritePropertyName(name); - return; - } - - writer.WritePropertyName(EnumHelpers.Info.FormatNumericValue(value)); - } - - /// Builds the three serialized-name maps from a single scan of the enum's fields, so the field - /// metadata and each field's camelCase name are computed once instead of once per map. - /// The ordinal and case-insensitive names-to-values maps and the values-to-names map. - internal static ( - Dictionary NamesToValues, - Dictionary NamesToValuesIgnoreCase, - Dictionary ValuesToNames) BuildNameMaps() - { - var fields = typeof(TEnum).GetFields(BindingFlags.Public | BindingFlags.Static); - - // Each field contributes its camelCase name and, when different, its declared name, so two entries per field - // is the upper bound for the name-keyed maps; presizing to it avoids the grow-and-rehash cycle. - var namesToValues = new Dictionary(fields.Length * MaxNamesPerField, StringComparer.Ordinal); - var namesToValuesIgnoreCase = new Dictionary(fields.Length * MaxNamesPerField, StringComparer.OrdinalIgnoreCase); - var valuesToNames = new Dictionary(fields.Length); - - foreach (var field in fields) - { - var value = EnumHelpers.Info.ParseName(field.Name); - var preferredName = GetPreferredSerializedName(field); - - // The single camelCase name string is shared as a key in both name maps and as the reverse-map value. - namesToValues[preferredName] = value; - namesToValuesIgnoreCase[preferredName] = value; - - // The declared name is a second lookup key only when it differs from the camelCase preferred name. - if (!string.Equals(field.Name, preferredName, StringComparison.Ordinal)) - { - namesToValues[field.Name] = value; - namesToValuesIgnoreCase[field.Name] = value; - } - - valuesToNames[value] = preferredName; - } - - return (namesToValues, namesToValuesIgnoreCase, valuesToNames); - } - - /// Reads an enum value from either a string name or a numeric value. - /// The reader positioned on the value to read. - /// The parsed enum value. - /// The value is an empty or whitespace string, a name that maps to no enum field, or a token that is neither a string nor a number. - internal TEnum ReadValue(ref Utf8JsonReader reader) - { - if (reader.TokenType is JsonTokenType.String or JsonTokenType.PropertyName) - { - var value = reader.GetString(); - if (value is null || string.IsNullOrWhiteSpace(value)) - { - throw new JsonException($"Cannot convert an empty value to {typeof(TEnum)}."); - } - - if (_namesToValues.TryGetValue(value!, out var namedValue)) - { - return namedValue; - } - - if (_namesToValuesIgnoreCase.TryGetValue(value!, out var namedValueIgnoreCase)) - { - return namedValueIgnoreCase; - } - - throw new JsonException($"Unable to convert '{value}' to {typeof(TEnum)}."); - } - - if (reader.TokenType == JsonTokenType.Number) - { - return EnumHelpers.Info.ReadJsonNumericValue(ref reader); - } - - throw new JsonException($"Unexpected token {reader.TokenType} when parsing {typeof(TEnum)}."); - } - } - - /// A strongly-typed JSON converter for nullable enums that maps values to and from camelCase names. - /// The underlying enum type. - internal sealed class NullableEnumConverter< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] TEnum> : JsonConverter - where TEnum : struct, Enum - { - /// The underlying non-nullable enum converter that performs the name/value mapping. - private readonly EnumConverter _inner = new(); - - /// - public override TEnum? Read( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) => - IsNullOrEmptyString(ref reader) ? null : _inner.Read(ref reader, typeof(TEnum), options); - - /// - public override void Write(Utf8JsonWriter writer, TEnum? value, JsonSerializerOptions options) - { - if (value is null) - { - writer.WriteNullValue(); - return; - } - - _inner.Write(writer, value.Value, options); - } - - /// - public override TEnum? ReadAsPropertyName( - ref Utf8JsonReader reader, - Type typeToConvert, - JsonSerializerOptions options) => - IsNullOrEmptyString(ref reader) ? null : _inner.ReadAsPropertyName(ref reader, typeof(TEnum), options); - - /// - public override void WriteAsPropertyName( - Utf8JsonWriter writer, - TEnum? value, - JsonSerializerOptions options) - { - if (value is null) - { - writer.WritePropertyName(string.Empty); - return; - } - - _inner.WriteAsPropertyName(writer, value.Value, options); - } - } -} diff --git a/src/Refit/ContentSerializerNameStyle.cs b/src/Refit/ContentSerializerNameStyle.cs new file mode 100644 index 000000000..ce3d51887 --- /dev/null +++ b/src/Refit/ContentSerializerNameStyle.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit; + +/// Identifies which serializer attribute family names a form field when the configured content serializer is asked. +public enum ContentSerializerNameStyle +{ + /// Field names come from [JsonPropertyName]. + SystemTextJson = 0, + + /// Field names come from Newtonsoft.Json's [JsonProperty]. + Newtonsoft = 1, + + /// Field names come from [XmlElement] or [XmlAttribute]. + Xml = 2, +} diff --git a/src/Refit/DefaultUrlParameterFormatter.cs b/src/Refit/DefaultUrlParameterFormatter.cs index 627dc70a1..3fa3a103c 100644 --- a/src/Refit/DefaultUrlParameterFormatter.cs +++ b/src/Refit/DefaultUrlParameterFormatter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for full license information. using System.Diagnostics.CodeAnalysis; -using System.Reflection; using System.Runtime.CompilerServices; namespace Refit; @@ -60,7 +59,7 @@ public void AddFormat(string format) => /// attributeProvider. public virtual string? Format( object? value, - ICustomAttributeProvider attributeProvider, + IParameterAttributeProvider attributeProvider, Type type) { ArgumentExceptionHelper.ThrowIfNull(attributeProvider); @@ -84,7 +83,7 @@ public void AddFormat(string format) => /// Gets the first query attribute from an attribute provider. /// The attribute provider to inspect. /// The first query attribute, or null when absent. - internal static QueryAttribute? GetFirstQueryAttribute(ICustomAttributeProvider attributeProvider) + internal static QueryAttribute? GetFirstQueryAttribute(IParameterAttributeProvider attributeProvider) { // IsDefined avoids materializing an attribute array when none is present. That matters for a Type provider // (used when formatting collection elements), whose GetCustomAttributes allocates even for an empty result, diff --git a/src/Refit/EnumHelpers.cs b/src/Refit/EnumHelpers.cs index 7626eb6d6..a4e768ed6 100644 --- a/src/Refit/EnumHelpers.cs +++ b/src/Refit/EnumHelpers.cs @@ -2,66 +2,33 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Collections.Concurrent; -using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Reflection; using System.Runtime.CompilerServices; -using System.Runtime.Serialization; using System.Text.Json; namespace Refit; -/// Provides shared enum helpers for formatting, serialization, and reflection-backed metadata. +/// Provides shared enum helpers for formatting and serialization. internal static class EnumHelpers { - /// Caches lookups by enum type and field name. - private static readonly ConcurrentDictionary> _enumMemberValueCache = new(); - - /// Gets the for a boxed enum value. + /// Gets the [EnumMember] value for a boxed enum value. /// The runtime enum type. /// The boxed enum value. - /// The configured enum member value, or null when none is configured. - internal static string? GetEnumMemberValue(Type enumType, object value) - { - if (!enumType.IsEnum) - { - return null; - } - - var name = Enum.GetName(enumType, value); - if (name is null) - { - return null; - } - - var enumMemberValues = _enumMemberValueCache.GetOrAdd(enumType, CreateEnumMemberValueMap); - return enumMemberValues.TryGetValue(name, out var enumMemberValue) ? enumMemberValue : null; - } - - /// Builds the enum-member value map for the given enum type. - /// The enum type to inspect. - /// The enum-member value map keyed by enum field name. - [UnconditionalSuppressMessage( - "Trimming", - "IL2070:DynamicallyAccessedMembers", - Justification = "Enum field metadata is inspected for EnumMemberAttribute formatting on runtime enum values.")] - internal static Dictionary CreateEnumMemberValueMap(Type enumType) - { - var fields = enumType.GetFields(BindingFlags.Public | BindingFlags.Static); - var enumMemberValues = new Dictionary(fields.Length, StringComparer.Ordinal); - for (var i = 0; i < fields.Length; i++) - { - var field = fields[i]; - var enumMemberAttribute = field.GetCustomAttribute(); - if (enumMemberAttribute is not null) - { - enumMemberValues[field.Name] = enumMemberAttribute.Value; - } - } - - return enumMemberValues; - } + /// The configured enum member value, or null when none is configured or the Refit.Reflection support is not registered. + /// Reading the attribute from a run-time-typed enum needs reflection, so it is supplied by Refit.Reflection. Enums + /// whose type the generator can see at compile time have their [EnumMember] values generated instead. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static string? GetEnumMemberValue(Type enumType, object value) => + GetEnumMemberValue(ReflectionHooks.EnumMemberValueResolver, enumType, value); + + /// Gets the [EnumMember] value for a boxed enum value through the supplied resolver. + /// The registered resolver, or when none is registered. + /// The runtime enum type. + /// The boxed enum value. + /// The configured enum member value, or null when none is configured or no resolver is registered. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static string? GetEnumMemberValue(Func? resolver, Type enumType, object value) => + resolver?.Invoke(enumType, value); /// Determines whether the given enum backing type code is unsigned. /// The enum backing type code. @@ -71,9 +38,7 @@ internal static bool IsUnsignedBackingType(TypeCode underlyingTypeCode) => /// Provides cached helpers for a single enum type. /// The enum type. - internal static class Info< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields)] - TEnum> + internal static class Info where TEnum : struct, Enum { /// The enum backing type used when reading and writing undefined numeric values. diff --git a/src/Refit/FormField.cs b/src/Refit/FormField.cs index 8e1cdaf86..fdf49fc2d 100644 --- a/src/Refit/FormField.cs +++ b/src/Refit/FormField.cs @@ -19,7 +19,7 @@ public sealed class FormField /// Initializes a new instance of the class. /// Reads the property value from a body instance without reflection. /// The declared CLR property name, used when no explicit name is configured. - /// The explicit field name from [AliasAs] or [JsonPropertyName], or . + /// The compile-time explicit and serializer-specific field names. /// The precomputed prefix + delimiter prepended to the field name, or when no prefix applies. /// The applied to the value, or . /// The explicit , or to use the settings default. @@ -27,7 +27,7 @@ public sealed class FormField public FormField( Func getter, string clrName, - string? explicitName, + FormFieldNames names, string? prefixSegment, string? format, CollectionFormat? collectionFormat, @@ -35,7 +35,7 @@ public FormField( { Getter = getter; ClrName = clrName; - ExplicitName = explicitName; + Names = names; PrefixSegment = prefixSegment; Format = format; CollectionFormat = collectionFormat; @@ -48,8 +48,8 @@ public FormField( /// Gets the declared CLR property name. public string ClrName { get; } - /// Gets the explicit field name from [AliasAs] or [JsonPropertyName], if any. - public string? ExplicitName { get; } + /// Gets the compile-time explicit and serializer-specific field names. + public FormFieldNames Names { get; } /// Gets the precomputed prefix + delimiter prepended to the field name, if any. public string? PrefixSegment { get; } @@ -65,10 +65,11 @@ public FormField( /// Resolves the form field name, applying the key formatter and any prefix. /// The formatter applied to the CLR name when no explicit name is set. + /// The attribute family the configured content serializer reads names from. /// The resolved field name. - public string? ResolveFieldName(IUrlParameterKeyFormatter urlParameterKeyFormatter) + public string? ResolveFieldName(IUrlParameterKeyFormatter urlParameterKeyFormatter, ContentSerializerNameStyle nameStyle) { - var name = ExplicitName ?? urlParameterKeyFormatter.Format(ClrName); + var name = Names.ExplicitName ?? Names.ForStyle(nameStyle) ?? urlParameterKeyFormatter.Format(ClrName); return PrefixSegment is null ? name : PrefixSegment + name; } } diff --git a/src/Refit/FormFieldNames.cs b/src/Refit/FormFieldNames.cs new file mode 100644 index 000000000..6724444f6 --- /dev/null +++ b/src/Refit/FormFieldNames.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. +using System.ComponentModel; + +namespace Refit; + +/// The compile-time names a form field can take, resolved by the Refit source generator. +/// The [AliasAs] or [Query] name, which wins over every serializer name, or . +/// The [JsonPropertyName] name used with a System.Text.Json serializer, or . +/// The Newtonsoft.Json [JsonProperty] name, or . +/// The [XmlElement] or [XmlAttribute] name, or . +[EditorBrowsable(EditorBrowsableState.Never)] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] // The only uncovered members are the compiler-generated record equality and formatting. +public readonly record struct FormFieldNames( + string? ExplicitName, + string? JsonName, + string? NewtonsoftName, + string? XmlName) +{ + /// Picks the serializer-specific name for the given attribute family. + /// The attribute family the configured content serializer reads names from. + /// The serializer name, or when the property has none for that family. + public string? ForStyle(ContentSerializerNameStyle nameStyle) => + nameStyle switch + { + ContentSerializerNameStyle.Newtonsoft => NewtonsoftName, + ContentSerializerNameStyle.Xml => XmlName, + _ => JsonName, + }; +} diff --git a/src/Refit/FormObjectAttribute.cs b/src/Refit/FormObjectAttribute.cs index a4046124c..c2408efeb 100644 --- a/src/Refit/FormObjectAttribute.cs +++ b/src/Refit/FormObjectAttribute.cs @@ -15,7 +15,7 @@ namespace Refit; /// ASP.NET [FromForm] model) receives the individual values. /// /// Field names are resolved per property in the same order as url-encoded body flattening: an explicit -/// , then , then +/// , then the configured content serializer's own field name, then /// . Values are rendered through /// , collections honour /// , and a nested object composes its children under a diff --git a/src/Refit/FormValueMultimap.cs b/src/Refit/FormValueMultimap.cs index 864a4a3e2..89baf2d76 100644 --- a/src/Refit/FormValueMultimap.cs +++ b/src/Refit/FormValueMultimap.cs @@ -5,7 +5,6 @@ using System.Collections; using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Reflection; using System.Runtime.CompilerServices; namespace Refit; @@ -16,53 +15,40 @@ namespace Refit; /// same or different values. internal sealed class FormValueMultimap : IEnumerable> { - /// The maximum object-graph depth flattened before deeper nested values are dropped, guarding against runaway recursion. - private const int MaxNestingDepth = 32; - /// The default delimiter composing a nested field key from its parent key, matching the query-flattening default. - private const string DefaultNestingDelimiter = "."; + internal const string DefaultNestingDelimiter = "."; - /// Caches the per-property attribute metadata for each source type without keeping collectible types alive. - /// The reflection form path reads and for every - /// property on every request. Those attributes are compile-time metadata that never change for a type, so they are - /// read once and reused, collapsing the per-property attribute lookups (the dominant allocation on this path) into a - /// single one-time-per-type cost. Field names still consult the settings' content serializer and key formatter per - /// call, so settings-dependent naming is never frozen. - private static readonly ConditionalWeakTable _metadataCache = new(); + /// The maximum object-graph depth flattened before deeper nested values are dropped, guarding against runaway recursion. + private const int MaxNestingDepth = 32; /// Holds the collected form key/value entries. private readonly List> _formEntries = []; - /// The content serializer used to resolve field names. - private readonly IHttpContentSerializer _contentSerializer; - - /// The formatter applied to property names that are not explicitly aliased. - private readonly IUrlParameterKeyFormatter _urlParameterKeyFormatter; - /// The complex values currently being flattened on the recursion path, guarding against reference cycles. private List? _ancestors; /// Initializes a new instance of the class from a source object. /// The source object or dictionary to convert into form entries. /// The Refit settings controlling formatting. - internal FormValueMultimap(object source, RefitSettings settings) - : this(source, settings, null) + internal FormValueMultimap(object? source, RefitSettings settings) + : this(source, source?.GetType(), settings) { } /// Initializes a new instance of the class from a source object. /// The source object or dictionary to convert into form entries. + /// The type whose readable public properties are flattened, or when there is no source. /// The Refit settings controlling formatting. - /// The cached attribute metadata for the declared source type, if available. - internal FormValueMultimap( - object? source, - RefitSettings settings, - FormPropertyMetadata[]? declaredMetadata) + [SuppressMessage( + "Correctness", + "SST2403", + Justification = "Every field is assigned before the registered flattener receives the map, and the class is sealed, so the flattener only sees a fully initialized instance.")] + internal FormValueMultimap(object? source, Type? sourceType, RefitSettings settings) { ArgumentExceptionHelper.ThrowIfNull(settings); - _contentSerializer = settings.ContentSerializer; - _urlParameterKeyFormatter = settings.UrlParameterKeyFormatter; + ContentSerializer = settings.ContentSerializer; + UrlParameterKeyFormatter = settings.UrlParameterKeyFormatter; if (source is null) { @@ -75,9 +61,16 @@ internal FormValueMultimap( return; } - AddObject(source, declaredMetadata ?? GetCachedMetadata(source.GetType()), settings, null, DefaultNestingDelimiter, 0); + ReflectionHooks.RequireFormObjectFlattener() + .AddObject(this, source, sourceType!, settings, null, DefaultNestingDelimiter, 0); } + /// Gets the content serializer used to resolve field names. + internal IHttpContentSerializer ContentSerializer { get; } + + /// Gets the formatter applied to property names that are not explicitly aliased. + internal IUrlParameterKeyFormatter UrlParameterKeyFormatter { get; } + /// Gets a key for each entry. If multiple entries share the same key, the key is returned multiple times. internal IEnumerable Keys => GetKeys(); @@ -95,35 +88,32 @@ internal FormValueMultimap( /// The source object or dictionary to convert into form entries. /// The Refit settings controlling formatting. /// The created form value map. - internal static FormValueMultimap Create< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] - TSource>( + internal static FormValueMultimap Create( TSource source, RefitSettings settings) => source is null or IDictionary - ? new(source!, settings) - : new FormValueMultimap( - source, - settings, - GetCachedMetadata(source)); + ? new(source, settings) + : new FormValueMultimap(source, typeof(TSource), settings); /// Creates a form value map from source-generated field descriptors, avoiding reflection. /// The declared body type. /// The body instance to flatten into form entries. /// The compile-time field descriptors for the body type. /// The Refit settings controlling formatting. + /// The attribute family the configured content serializer reads names from. /// The created form value map. internal static FormValueMultimap CreateFromFields( TBody body, FormField[] fields, - RefitSettings settings) + RefitSettings settings, + ContentSerializerNameStyle nameStyle) { - var map = new FormValueMultimap(null, settings, null); + var map = new FormValueMultimap(null, settings); for (var i = 0; i < fields.Length; i++) { var field = fields[i]; var value = field.Getter(body); - var fieldName = field.ResolveFieldName(map._urlParameterKeyFormatter); + var fieldName = field.ResolveFieldName(map.UrlParameterKeyFormatter, nameStyle); if (value is null) { @@ -141,54 +131,6 @@ internal static FormValueMultimap CreateFromFields( return map; } - /// Resolves the cached per-property attribute metadata for the given source type. - /// The type to inspect. - /// The cached attribute metadata for each readable public property. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage( - "Trimming", - "IL2111:Method with DynamicallyAccessedMembersAttribute is accessed via reflection", - Justification = "The cache callback receives the same Type key that carries the public property metadata requirement.")] - internal static FormPropertyMetadata[] GetCachedMetadata(Type type) => - _metadataCache.GetValue(type, BuildMetadata); - - /// Resolves the cached per-property attribute metadata for the given declared source type. - /// The declared source type to inspect. - /// A value of the declared source type. - /// The cached attribute metadata for each readable public property. - internal static FormPropertyMetadata[] GetCachedMetadata< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] - TSource>(TSource source) - { - _ = source; - - return _metadataCache.GetValue(typeof(TSource), static _ => BuildMetadata(typeof(TSource))); - } - - /// Reads the attribute metadata for each readable public property of the given type. - /// The type whose properties are inspected. - /// The attribute metadata array, in property order. - /// Runs once per type as the cache miss callback: the name and the - /// are read here and reused for every subsequent request instead of being re-read per - /// property per call. - internal static FormPropertyMetadata[] BuildMetadata( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] - Type type) - { - var properties = ReflectionPropertyHelpers.GetReadablePublicInstanceProperties(type); - var metadata = new FormPropertyMetadata[properties.Length]; - for (var i = 0; i < properties.Length; i++) - { - var property = properties[i]; - metadata[i] = new( - property, - property.GetCustomAttribute(true)?.Name, - property.GetCustomAttribute(true)); - } - - return metadata; - } - /// Gets the delimiter string for a delimited collection format. /// The delimited collection format. /// The delimiter string. @@ -291,53 +233,6 @@ internal void AddDictionary( } } - /// Adds the entries reflected from an object source, composing nested keys under the given prefix. - /// The object source. - /// The cached attribute metadata for the source's readable public properties. - /// The Refit settings controlling formatting. - /// The parent key prefix, or for a top-level object. - /// The delimiter composing each property key under the prefix. - /// The current nesting depth. - internal void AddObject( - object source, - FormPropertyMetadata[] metadata, - RefitSettings settings, - string? keyPrefix, - string? delimiter, - int depth) - { - for (var i = 0; i < metadata.Length; i++) - { - var property = metadata[i].Property; - var value = property.GetValue(source, null); - - // The query attribute was read once when the metadata was cached for this type. - var attrib = metadata[i].Query; - - var fieldName = ComposeKey(keyPrefix, GetFieldNameForProperty(metadata[i]), delimiter); - - if (value is null) - { - if (attrib?.SerializeNull == true) - { - Add(fieldName, string.Empty); - } - - continue; - } - - var collectionFormat = attrib?.IsCollectionFormatSpecified == true - ? attrib.CollectionFormat - : (CollectionFormat?)null; - - // A nested object/dictionary composes its children under this property's key using this property's own - // [Query] delimiter when present, otherwise the inherited delimiter (matching the query-flattening path). - var nestedDelimiter = attrib is not null ? attrib.Delimiter : (delimiter ?? DefaultNestingDelimiter); - - AppendValue(fieldName, value, attrib?.Format, collectionFormat, settings, nestedDelimiter, depth); - } - } - /// Adds a non-null property or descriptor value, choosing scalar, collection, dictionary, or nested-object handling. /// The resolved form field name. /// The non-null value to add. @@ -389,7 +284,8 @@ internal void AppendValue( return; } - AddObject(value, GetCachedMetadata(value.GetType()), settings, fieldName, delimiter, depth + 1); + ReflectionHooks.RequireFormObjectFlattener() + .AddObject(this, value, value.GetType(), settings, fieldName, delimiter, depth + 1); ExitComplex(); } @@ -495,32 +391,4 @@ or CollectionFormat.Tsv yield return _formEntries[i].Key; } } - - /// Resolves the form field name for the given property from its cached attribute metadata. - /// The cached attribute metadata for the property. - /// The resolved form field name. - /// The name and come from the per-type cache; - /// the content serializer and key formatter are still consulted per call because they are settings-dependent. - internal string GetFieldNameForProperty(in FormPropertyMetadata metadata) - { - var name = metadata.AliasName - ?? metadata.Query?.Name - ?? _contentSerializer.GetFieldNameForProperty(metadata.Property) - ?? _urlParameterKeyFormatter.Format(metadata.Property.Name); - - var qattrib = metadata.Query; - return qattrib is not null && !string.IsNullOrWhiteSpace(qattrib.Prefix) - ? qattrib.Prefix + qattrib.Delimiter + name - : name; - } - - /// The cached, settings-independent attribute metadata for a single readable public property on a form - /// source type, read once when the property list is first cached and reused for every request. - /// The reflected property. - /// The override, or when absent. - /// The applied to the property, or when absent. - internal readonly record struct FormPropertyMetadata( - PropertyInfo Property, - string? AliasName, - QueryAttribute? Query); } diff --git a/src/Refit/GeneratedOnlyRequestBuilder.cs b/src/Refit/GeneratedOnlyRequestBuilder.cs index 7d7f1727d..599c9b753 100644 --- a/src/Refit/GeneratedOnlyRequestBuilder.cs +++ b/src/Refit/GeneratedOnlyRequestBuilder.cs @@ -1,8 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Diagnostics.CodeAnalysis; - namespace Refit; /// Request builder used by generated-only clients. @@ -16,8 +14,6 @@ internal sealed class GeneratedOnlyRequestBuilder : IRequestBuilder public RefitSettings Settings { get; } /// - [RequiresUnreferencedCode("Building request delegates from reflected method metadata requires generic method metadata to be available at runtime.")] - [RequiresDynamicCode("Building request delegates from reflected method metadata requires runtime generic method instantiation.")] public Func BuildRestResultFuncForMethod( string methodName, Type[]? parameterTypes = null, diff --git a/src/Refit/GeneratedParameterAttributeProvider.cs b/src/Refit/GeneratedParameterAttributeProvider.cs index 9568c745e..3781531dd 100644 --- a/src/Refit/GeneratedParameterAttributeProvider.cs +++ b/src/Refit/GeneratedParameterAttributeProvider.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; using System.Runtime.CompilerServices; namespace Refit; @@ -11,7 +10,7 @@ namespace Refit; /// instead when every attribute has the same type. /// The attribute information. [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider(Dictionary attributes) : ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider(Dictionary attributes) : IParameterAttributeProvider { /// A shared provider for parameters that declare no attributes, avoiding a per-parameter empty dictionary. public static readonly GeneratedParameterAttributeProvider Empty = new([]); diff --git a/src/Refit/GeneratedRequestRunner.BodyContent.cs b/src/Refit/GeneratedRequestRunner.BodyContent.cs index 8c3d04832..4961a6409 100644 --- a/src/Refit/GeneratedRequestRunner.BodyContent.cs +++ b/src/Refit/GeneratedRequestRunner.BodyContent.cs @@ -125,7 +125,7 @@ public static HttpContent CreateTypedJsonLinesBodyContent( IEnumerable? body) => body is null or HttpContent or Stream || settings.ContentSerializer is not SystemTextJsonContentSerializer serializer - || !serializer.WritesDeclaredTypeAsObject(typeof(TElement)) + || !SystemTextJsonContentSerializer.WritesDeclaredTypeAsObject(typeof(TElement)) ? CreateJsonLinesBodyContent(settings, body) : new JsonLinesContent(body, serializer); @@ -151,9 +151,7 @@ body is null or HttpContent or Stream "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Generated callers specify the declared body type for AOT-safe form property discovery.")] - public static HttpContent CreateUrlEncodedBodyContent< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] - TBody>( + public static HttpContent CreateUrlEncodedBodyContent( RefitSettings settings, TBody body) { @@ -191,9 +189,7 @@ public static HttpContent CreateUrlEncodedBodyContent< "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Generated callers specify the declared body type for AOT-safe form property discovery.")] - public static HttpContent CreateUrlEncodedBodyContent< - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] - TBody>( + public static HttpContent CreateUrlEncodedBodyContent( RefitSettings settings, TBody body, FormField[] fields) @@ -217,13 +213,13 @@ public static HttpContent CreateUrlEncodedBodyContent< } // The descriptor path only matches the reflection path when the serializer resolves field names from - // attributes the generator already inlined (the built-in System.Text.Json serializer); otherwise fall back. + // attributes the generator already inlined (a serializer that reports its name style); otherwise fall back. var useDescriptors = body is not null and not System.Collections.IDictionary - && settings.ContentSerializer is SystemTextJsonContentSerializer; + && settings.ContentSerializer is IContentSerializerNameStyle; return new FormUrlEncodedContent( useDescriptors - ? FormValueMultimap.CreateFromFields(body, fields, settings) + ? FormValueMultimap.CreateFromFields(body, fields, settings, ((IContentSerializerNameStyle)settings.ContentSerializer).NameStyle) : FormValueMultimap.Create(body, settings)); } diff --git a/src/Refit/GeneratedRequestRunner.cs b/src/Refit/GeneratedRequestRunner.cs index af12b7207..623acebc4 100644 --- a/src/Refit/GeneratedRequestRunner.cs +++ b/src/Refit/GeneratedRequestRunner.cs @@ -285,7 +285,7 @@ public static string BuildRequestPath( public static string RoundTripEscapePath( string? value, RefitSettings settings, - ICustomAttributeProvider attributeProvider, + IParameterAttributeProvider attributeProvider, Type type) { if (value is null) @@ -345,7 +345,7 @@ public static string RoundTripEscapePath( public static string? FormatUrlParameter( RefitSettings settings, object? value, - ICustomAttributeProvider attributeProvider, + IParameterAttributeProvider attributeProvider, Type type) => ResolveUrlParameterFormatter(settings, value).Format(value, attributeProvider, type); @@ -402,6 +402,31 @@ public static string BuildQueryKey( return prefixSegment is null ? name : prefixSegment + name; } + /// Builds a form field key, choosing the compile-time name that matches the configured content serializer. + /// The Refit settings. + /// The declared CLR property name. + /// The [AliasAs] or [Query] name, which wins over every serializer name, or null. + /// The [JsonPropertyName] name, or null. + /// The Newtonsoft.Json [JsonProperty] name, or null. + /// The [XmlElement] or [XmlAttribute] name, or null. + /// The compile-time prefix + delimiter, or null. + /// The form field key. + /// Generated code only calls this after checking the serializer implements . + public static string BuildFormKey( + RefitSettings settings, + string clrName, + string? explicitName, + string? jsonName, + string? newtonsoftName, + string? xmlName, + string? prefixSegment) + { + var serializerName = new FormFieldNames(explicitName, jsonName, newtonsoftName, xmlName) + .ForStyle(((IContentSerializerNameStyle)settings.ContentSerializer).NameStyle); + + return BuildQueryKey(settings, clrName, explicitName ?? serializerName, prefixSegment); + } + /// Formats a value with the invariant culture, matching the default URL parameter formatter's /// rendering for values without boxing or reflection. /// The formattable value type. @@ -445,7 +470,7 @@ public static void AddFormattedCollectionProperty( string key, CollectionFormat collectionFormat, bool preEncoded, - (Type ElementProviderType, ICustomAttributeProvider JoinedProvider, Type JoinedType) formatting) + (Type ElementProviderType, IParameterAttributeProvider JoinedProvider, Type JoinedType) formatting) { if (values is null) { @@ -457,7 +482,7 @@ public static void AddFormattedCollectionProperty( { foreach (var value in values) { - var formatted = FormatUrlParameter(settings, value, element, element); + var formatted = FormatUrlParameter(settings, value, GeneratedParameterAttributeProvider.Empty, element); builder.Add(key, FormatUrlParameter(settings, formatted, formatting.JoinedProvider, formatting.JoinedType), preEncoded); } @@ -635,7 +660,7 @@ internal static string JoinFormattedElements( } first = false; - builder.Append(FormatUrlParameter(settings, value, elementProviderType, elementProviderType)); + builder.Append(FormatUrlParameter(settings, value, GeneratedParameterAttributeProvider.Empty, elementProviderType)); } return builder.ToString(); @@ -801,7 +826,7 @@ private static void AppendFormattedSection( ref ValueStringBuilder sb, string section, RefitSettings settings, - ICustomAttributeProvider attributeProvider, + IParameterAttributeProvider attributeProvider, Type type) => sb.Append(StringHelpers.EscapeDataString(FormatUrlParameter(settings, section, attributeProvider, type) ?? string.Empty)); } diff --git a/src/Refit/GeneratedSingleTypeParameterAttributeProvider.cs b/src/Refit/GeneratedSingleTypeParameterAttributeProvider.cs index 3acd065de..c7f5706c8 100644 --- a/src/Refit/GeneratedSingleTypeParameterAttributeProvider.cs +++ b/src/Refit/GeneratedSingleTypeParameterAttributeProvider.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; using System.Runtime.CompilerServices; namespace Refit; @@ -13,7 +12,7 @@ namespace Refit; /// The attribute type every entry of has. /// The attribute information. [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider(Type type, object[] attributes) : ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider(Type type, object[] attributes) : IParameterAttributeProvider { /// [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/Refit/HttpRetryHandler.cs b/src/Refit/HttpRetryHandler.cs index c2ab62839..5f4f6e13f 100644 --- a/src/Refit/HttpRetryHandler.cs +++ b/src/Refit/HttpRetryHandler.cs @@ -92,7 +92,8 @@ private static RetryConfiguration ValidateOptions(HttpRetryOptions options) throw new ArgumentOutOfRangeException(nameof(options.BaseDelay)); } - if (options.MaxDelay < TimeSpan.Zero || options.MaxDelay.TotalMilliseconds > uint.MaxValue - 1D) + // BaseDelay is already known to be non-negative and no greater than MaxDelay, so MaxDelay cannot be negative. + if (options.MaxDelay.TotalMilliseconds > uint.MaxValue - 1D) { throw new ArgumentOutOfRangeException(nameof(options.MaxDelay)); } diff --git a/src/Refit/IContentSerializerNameStyle.cs b/src/Refit/IContentSerializerNameStyle.cs new file mode 100644 index 000000000..c10c70e7e --- /dev/null +++ b/src/Refit/IContentSerializerNameStyle.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit; + +/// +/// Implemented by a content serializer whose property names come from a known attribute family, so generated +/// code can pick the right compile-time name for a form field without reflection. +/// +public interface IContentSerializerNameStyle +{ + /// Gets the attribute family this serializer reads property names from. + ContentSerializerNameStyle NameStyle { get; } +} diff --git a/src/Refit/IFormObjectFlattener.cs b/src/Refit/IFormObjectFlattener.cs new file mode 100644 index 000000000..492b8f4e7 --- /dev/null +++ b/src/Refit/IFormObjectFlattener.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit; + +/// +/// Flattens a complex object whose properties are only known at run time into form entries. Core Refit has no +/// implementation; the Refit.Reflection package registers one when it loads. +/// +internal interface IFormObjectFlattener +{ + /// Adds the entries for an object source, composing nested keys under the given prefix. + /// The form map the entries are added to. + /// The object source. + /// The type whose readable public properties are flattened: the declared type at the top level, the run-time type when nested. + /// The Refit settings controlling formatting. + /// The parent key prefix, or for a top-level object. + /// The delimiter composing each property key under the prefix. + /// The current nesting depth. + void AddObject( + FormValueMultimap map, + object source, + Type sourceType, + RefitSettings settings, + string? keyPrefix, + string? delimiter, + int depth); +} diff --git a/src/Refit/IHttpContentSerializer.cs b/src/Refit/IHttpContentSerializer.cs index c87d91659..a20c18359 100644 --- a/src/Refit/IHttpContentSerializer.cs +++ b/src/Refit/IHttpContentSerializer.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for full license information. using System.Diagnostics.CodeAnalysis; -using System.Reflection; namespace Refit; @@ -40,11 +39,4 @@ public interface IHttpContentSerializer Task FromHttpContentAsync( HttpContent content, CancellationToken cancellationToken = default); - - /// - /// Calculates what the field name should be for the given property. This may be affected by custom attributes the serializer understands. - /// - /// A PropertyInfo object. - /// The calculated field name. - string? GetFieldNameForProperty(PropertyInfo propertyInfo); } diff --git a/src/Refit/IParameterAttributeProvider.cs b/src/Refit/IParameterAttributeProvider.cs new file mode 100644 index 000000000..424267502 --- /dev/null +++ b/src/Refit/IParameterAttributeProvider.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit; + +/// Exposes the attributes declared on a request parameter or property, as precomputed by the generator or read by Refit.Reflection. +public interface IParameterAttributeProvider +{ + /// Gets all the attributes declared on the parameter or property. + /// Whether to search the inheritance chain. + /// The attributes, or an empty array. + object[] GetCustomAttributes(bool inherit); + + /// Gets the attributes of the given type declared on the parameter or property. + /// The attribute type to look for. + /// Whether to search the inheritance chain. + /// The matching attributes, or an empty array. + object[] GetCustomAttributes(Type attributeType, bool inherit); + + /// Determines whether an attribute of the given type is declared on the parameter or property. + /// The attribute type to look for. + /// Whether to search the inheritance chain. + /// when at least one matching attribute is declared. + bool IsDefined(Type attributeType, bool inherit); +} diff --git a/src/Refit/IRequestBuilder.cs b/src/Refit/IRequestBuilder.cs index 0cd541d36..20b9e6e2f 100644 --- a/src/Refit/IRequestBuilder.cs +++ b/src/Refit/IRequestBuilder.cs @@ -35,8 +35,6 @@ public interface IRequestBuilder "Design", "SST2309:An externally visible member declares an optional parameter, so callers bake in the default", Justification = "The optional parameters are part of Refit's public request-builder contract and are relied on by the Refit source generator and existing callers.")] - [RequiresUnreferencedCode("Building request delegates from reflected method metadata requires generic method metadata to be available at runtime.")] - [RequiresDynamicCode("Building request delegates from reflected method metadata requires runtime generic method instantiation.")] Func BuildRestResultFuncForMethod( string methodName, Type[]? parameterTypes = null, diff --git a/src/Refit/IRequestBuilderFactory.cs b/src/Refit/IRequestBuilderFactory.cs deleted file mode 100644 index 5598d17b1..000000000 --- a/src/Refit/IRequestBuilderFactory.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. -// ReactiveUI and Contributors licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. -using System.Diagnostics.CodeAnalysis; - -namespace Refit; - -/// Creates request builders for Refit interface types. -internal interface IRequestBuilderFactory -{ - /// Creates a strongly typed request builder for the specified interface type. - /// The Refit interface type. - /// The settings to configure the builder. - /// A request builder for the interface type. - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - IRequestBuilder Create< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(RefitSettings? settings); - - /// Creates a request builder for the specified interface type. - /// The Refit interface type. - /// The settings to configure the builder. - /// A request builder for the interface type. - [RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - IRequestBuilder Create( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - RefitSettings? settings); -} diff --git a/src/Refit/IUrlParameterFormatter.cs b/src/Refit/IUrlParameterFormatter.cs index ea8dff9b5..7954223d1 100644 --- a/src/Refit/IUrlParameterFormatter.cs +++ b/src/Refit/IUrlParameterFormatter.cs @@ -2,8 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; - namespace Refit; /// Provides Url parameter formatting. @@ -14,5 +12,5 @@ public interface IUrlParameterFormatter /// The attribute provider. /// Container class type. /// The formatted value, or null when is null. - string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type); + string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type); } diff --git a/src/Refit/JsonContentSerializer.cs b/src/Refit/JsonContentSerializer.cs index 5d948c7b8..7ffef7a4d 100644 --- a/src/Refit/JsonContentSerializer.cs +++ b/src/Refit/JsonContentSerializer.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. using System.Diagnostics.CodeAnalysis; -using System.Reflection; namespace Refit; @@ -43,15 +42,4 @@ public class JsonContentSerializer : IHttpContentSerializer public Task FromHttpContentAsync( HttpContent content, CancellationToken cancellationToken = default) => throw new NotSupportedException(); - - /// - /// Calculates what the field name should be for the given property. This may be affected by custom attributes the serializer understands. - /// - /// A PropertyInfo object. - /// - /// The calculated field name. - /// - /// Always thrown; this serializer is obsolete. - public string GetFieldNameForProperty(PropertyInfo propertyInfo) => - throw new NotSupportedException(); } diff --git a/src/Refit/JsonLinesContent{T}.cs b/src/Refit/JsonLinesContent{T}.cs index e1b719c0c..63596f92b 100644 --- a/src/Refit/JsonLinesContent{T}.cs +++ b/src/Refit/JsonLinesContent{T}.cs @@ -213,23 +213,34 @@ private async Task WriteItemsAsync(IEnumerable items, Stream stream, Cancella /// The request body stream. /// The send's cancellation token, also passed to the producer. /// A task that completes when the sequence has been written. + [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] // The compiler's rethrow edge after an awaited disposal in finally cannot be exercised or removed. private async Task WriteAsyncItemsAsync(IAsyncEnumerable items, Stream stream, CancellationToken cancellationToken) { var enumerator = items.GetAsyncEnumerator(cancellationToken); try { - var unflushed = false; - while (await MoveNextAsync(enumerator, stream, unflushed, cancellationToken).ConfigureAwait(false)) - { - // Terminate every line, so a server reading line by line can act on it before the next one exists. - await WriteItemAsync(stream, enumerator.Current, cancellationToken).ConfigureAwait(false); - await WriteLineSeparatorAsync(stream, cancellationToken).ConfigureAwait(false); - unflushed = true; - } + await WriteEnumeratedItemsAsync(enumerator, stream, cancellationToken).ConfigureAwait(false); } finally { await enumerator.DisposeAsync().ConfigureAwait(false); } } + + /// Writes each element of an enumerator, one per line, flushing before waiting on the producer. + /// The enumerator to drain. + /// The request body stream. + /// The send's cancellation token. + /// A task that completes when the enumerator has been drained. + private async Task WriteEnumeratedItemsAsync(IAsyncEnumerator enumerator, Stream stream, CancellationToken cancellationToken) + { + var unflushed = false; + while (await MoveNextAsync(enumerator, stream, unflushed, cancellationToken).ConfigureAwait(false)) + { + // Terminate every line, so a server reading line by line can act on it before the next one exists. + await WriteItemAsync(stream, enumerator.Current, cancellationToken).ConfigureAwait(false); + await WriteLineSeparatorAsync(stream, cancellationToken).ConfigureAwait(false); + unflushed = true; + } + } } diff --git a/src/Refit/ProblemDetails.cs b/src/Refit/ProblemDetails.cs index abdc588fe..4f708921b 100644 --- a/src/Refit/ProblemDetails.cs +++ b/src/Refit/ProblemDetails.cs @@ -1,8 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Text.Json.Serialization; - namespace Refit; /// The object representing the details about a ValidationException caught by a service implementing RFC 7807. @@ -13,7 +11,6 @@ public class ProblemDetails public Dictionary Errors { get; init; } = []; /// Gets the collection of ProblemDetails extensions. - [JsonExtensionData] public IDictionary Extensions { get; init; } = new Dictionary(StringComparer.Ordinal); diff --git a/src/Refit/ProblemDetailsJsonContext.cs b/src/Refit/ProblemDetailsJsonContext.cs deleted file mode 100644 index 5173a0eb4..000000000 --- a/src/Refit/ProblemDetailsJsonContext.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. -// ReactiveUI and Contributors licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. -using System.Text.Json.Serialization; - -namespace Refit; - -/// Source-generated JSON metadata used by built-in problem-details handling. -[JsonSerializable(typeof(ProblemDetails))] -[JsonSourceGenerationOptions( - PropertyNameCaseInsensitive = true, - PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, - Converters = [typeof(ObjectToInferredTypesConverter)])] -internal sealed partial class ProblemDetailsJsonContext : JsonSerializerContext; diff --git a/src/Refit/PublicAPI/net10.0/PublicAPI.txt b/src/Refit/PublicAPI/net10.0/PublicAPI.txt index 5e320f295..97c01855a 100644 --- a/src/Refit/PublicAPI/net10.0/PublicAPI.txt +++ b/src/Refit/PublicAPI/net10.0/PublicAPI.txt @@ -169,6 +169,12 @@ public enum CollectionFormat Multi = 5, Indexed = 6, } +public enum ContentSerializerNameStyle +{ + SystemTextJson = 0, + Newtonsoft = 1, + Xml = 2, +} [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultApiExceptionFactory { @@ -189,7 +195,7 @@ public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter public void AddFormat(string format) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public virtual string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter @@ -221,15 +227,27 @@ public class FileInfoPart : Refit.MultipartItem [System.Diagnostics.DebuggerDisplay("{Getter}")] public sealed class FormField { - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } + public FormField(System.Func getter, string clrName, Refit.FormFieldNames names, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } public string ClrName { get; } public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } public string? Format { get; } public System.Func Getter { get; } + public Refit.FormFieldNames Names { get; } public string? PrefixSegment { get; } public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } + public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter, Refit.ContentSerializerNameStyle nameStyle) { } +} +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly record struct FormFieldNames : System.IEquatable +{ + public FormFieldNames(string? ExplicitName, string? JsonName, string? NewtonsoftName, string? XmlName) { } + public string? ExplicitName { get; init; } + public string? JsonName { get; init; } + public string? NewtonsoftName { get; init; } + public string? XmlName { get; init; } + public readonly string? ForStyle(Refit.ContentSerializerNameStyle nameStyle) { } } [System.AttributeUsage(System.AttributeTargets.Parameter)] [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -248,7 +266,7 @@ public static class GeneratedPaging public static System.Uri? ToLink(string? link) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } public static readonly Refit.GeneratedParameterAttributeProvider Empty; @@ -278,10 +296,11 @@ public ref struct GeneratedQueryStringBuilder public static class GeneratedRequestRunner { public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } + public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, Refit.IParameterAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } + public static string BuildFormKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? jsonName, string? newtonsoftName, string? xmlName, string? prefixSegment) { } public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } @@ -305,10 +324,10 @@ public static class GeneratedRequestRunner [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static string RequireAbsoluteUrl(object? url) { } public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } @@ -325,7 +344,7 @@ public static class GeneratedRequestRunner public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -469,6 +488,10 @@ public interface IApiResponse : Refit.IApiResponse [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] bool IsSuccessfulWithContent { get; } } +public interface IContentSerializerNameStyle +{ + Refit.ContentSerializerNameStyle NameStyle { get; } +} public interface IFormUrlEncodedParameterFormatter { string? Format(object? value, string? formatString) { } @@ -476,7 +499,6 @@ public interface IFormUrlEncodedParameterFormatter public interface IHttpContentSerializer { System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } System.Net.Http.HttpContent ToHttpContent(T item) { } } public interface IJsonTypeInfoContentSerializer @@ -488,6 +510,12 @@ public interface IJsonTypeInfoContentSerializer System.Net.Http.HttpContent ToHttpContentSynchronous(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } System.Net.Http.HttpContent ToStreamingHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } } +public interface IParameterAttributeProvider +{ + object[] GetCustomAttributes(bool inherit) { } + object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } + bool IsDefined(System.Type attributeType, bool inherit) { } +} public interface IQueryConverter { void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } @@ -495,8 +523,6 @@ public interface IQueryConverter public interface IRequestBuilder { Refit.RefitSettings Settings { get; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Building request delegates from reflected method metadata requires runtime generic method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building request delegates from reflected method metadata requires generic method metadata to be available at runtime.")] System.Func BuildRestResultFuncForMethod(string methodName, System.Type[]? parameterTypes = null, System.Type[]? genericArgumentTypes = null) { } } public interface IRequestBuilder : Refit.IRequestBuilder @@ -521,7 +547,7 @@ public interface ISynchronousContentSerializer } public interface IUrlParameterFormatter { - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } public interface IUrlParameterKeyFormatter { @@ -534,7 +560,6 @@ public class JsonContentSerializer : Refit.IHttpContentSerializer { public JsonContentSerializer() { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -587,13 +612,6 @@ public sealed class NextLinkOriginPolicy public override string ToString() { } public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} [System.AttributeUsage(System.AttributeTargets.Method)] [System.Diagnostics.DebuggerDisplay("{Method}")] public sealed class OptionsAttribute : Refit.HttpMethodAttribute @@ -688,7 +706,6 @@ public class ProblemDetails public ProblemDetails() { } public string? Detail { get; set; } public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] public System.Collections.Generic.IDictionary Extensions { get; init; } public string? Instance { get; set; } public int Status { get; set; } @@ -852,21 +869,6 @@ public enum RequestBodySerializationMode Buffered = 1, Streamed = 2, } -public static class RequestBuilder -{ - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} public enum RequestCompression { Default = 0, @@ -882,63 +884,9 @@ public sealed class RequestCompressionOptions public System.IO.Compression.BrotliCompressionOptions? Brotli { get; set; } public System.IO.Compression.ZLibCompressionOptions? GZip { get; set; } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} public static class RestService { public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client by Type requires runtime type lookup and constructor metadata.")] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and constructor metadata.")] - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For(string hostUrl, Refit.RefitSettings? settings) { } public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -1008,10 +956,11 @@ public enum StreamingContentFormat ServerSentEvents = 2, } [System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IJsonTypeInfoContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer +public sealed class SystemTextJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.IJsonTypeInfoContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer { public SystemTextJsonContentSerializer() { } public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } @@ -1021,7 +970,6 @@ public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } public System.Net.Http.HttpContent ToHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } diff --git a/src/Refit/PublicAPI/net11.0/PublicAPI.txt b/src/Refit/PublicAPI/net11.0/PublicAPI.txt index f3eec8ab4..7040ef652 100644 --- a/src/Refit/PublicAPI/net11.0/PublicAPI.txt +++ b/src/Refit/PublicAPI/net11.0/PublicAPI.txt @@ -169,6 +169,12 @@ public enum CollectionFormat Multi = 5, Indexed = 6, } +public enum ContentSerializerNameStyle +{ + SystemTextJson = 0, + Newtonsoft = 1, + Xml = 2, +} [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultApiExceptionFactory { @@ -189,7 +195,7 @@ public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter public void AddFormat(string format) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public virtual string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter @@ -221,15 +227,27 @@ public class FileInfoPart : Refit.MultipartItem [System.Diagnostics.DebuggerDisplay("{Getter}")] public sealed class FormField { - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } + public FormField(System.Func getter, string clrName, Refit.FormFieldNames names, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } public string ClrName { get; } public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } public string? Format { get; } public System.Func Getter { get; } + public Refit.FormFieldNames Names { get; } public string? PrefixSegment { get; } public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } + public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter, Refit.ContentSerializerNameStyle nameStyle) { } +} +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly record struct FormFieldNames : System.IEquatable +{ + public FormFieldNames(string? ExplicitName, string? JsonName, string? NewtonsoftName, string? XmlName) { } + public string? ExplicitName { get; init; } + public string? JsonName { get; init; } + public string? NewtonsoftName { get; init; } + public string? XmlName { get; init; } + public readonly string? ForStyle(Refit.ContentSerializerNameStyle nameStyle) { } } [System.AttributeUsage(System.AttributeTargets.Parameter)] [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -248,7 +266,7 @@ public static class GeneratedPaging public static System.Uri? ToLink(string? link) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } public static readonly Refit.GeneratedParameterAttributeProvider Empty; @@ -278,10 +296,11 @@ public ref struct GeneratedQueryStringBuilder public static class GeneratedRequestRunner { public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } + public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, Refit.IParameterAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } + public static string BuildFormKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? jsonName, string? newtonsoftName, string? xmlName, string? prefixSegment) { } public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } @@ -305,10 +324,10 @@ public static class GeneratedRequestRunner [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static string RequireAbsoluteUrl(object? url) { } public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } @@ -325,7 +344,7 @@ public static class GeneratedRequestRunner public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -469,6 +488,10 @@ public interface IApiResponse : Refit.IApiResponse [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] bool IsSuccessfulWithContent { get; } } +public interface IContentSerializerNameStyle +{ + Refit.ContentSerializerNameStyle NameStyle { get; } +} public interface IFormUrlEncodedParameterFormatter { string? Format(object? value, string? formatString) { } @@ -476,7 +499,6 @@ public interface IFormUrlEncodedParameterFormatter public interface IHttpContentSerializer { System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } System.Net.Http.HttpContent ToHttpContent(T item) { } } public interface IJsonTypeInfoContentSerializer @@ -488,6 +510,12 @@ public interface IJsonTypeInfoContentSerializer System.Net.Http.HttpContent ToHttpContentSynchronous(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } System.Net.Http.HttpContent ToStreamingHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } } +public interface IParameterAttributeProvider +{ + object[] GetCustomAttributes(bool inherit) { } + object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } + bool IsDefined(System.Type attributeType, bool inherit) { } +} public interface IQueryConverter { void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } @@ -495,8 +523,6 @@ public interface IQueryConverter public interface IRequestBuilder { Refit.RefitSettings Settings { get; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Building request delegates from reflected method metadata requires runtime generic method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building request delegates from reflected method metadata requires generic method metadata to be available at runtime.")] System.Func BuildRestResultFuncForMethod(string methodName, System.Type[]? parameterTypes = null, System.Type[]? genericArgumentTypes = null) { } } public interface IRequestBuilder : Refit.IRequestBuilder @@ -521,7 +547,7 @@ public interface ISynchronousContentSerializer } public interface IUrlParameterFormatter { - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } public interface IUrlParameterKeyFormatter { @@ -534,7 +560,6 @@ public class JsonContentSerializer : Refit.IHttpContentSerializer { public JsonContentSerializer() { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -587,13 +612,6 @@ public sealed class NextLinkOriginPolicy public override string ToString() { } public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} [System.AttributeUsage(System.AttributeTargets.Method)] [System.Diagnostics.DebuggerDisplay("{Method}")] public sealed class OptionsAttribute : Refit.HttpMethodAttribute @@ -688,7 +706,6 @@ public class ProblemDetails public ProblemDetails() { } public string? Detail { get; set; } public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] public System.Collections.Generic.IDictionary Extensions { get; init; } public string? Instance { get; set; } public int Status { get; set; } @@ -852,21 +869,6 @@ public enum RequestBodySerializationMode Buffered = 1, Streamed = 2, } -public static class RequestBuilder -{ - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} public enum RequestCompression { Default = 0, @@ -883,63 +885,9 @@ public sealed class RequestCompressionOptions public System.IO.Compression.ZLibCompressionOptions? GZip { get; set; } public System.IO.Compression.ZstandardCompressionOptions? Zstandard { get; set; } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} public static class RestService { public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client by Type requires runtime type lookup and constructor metadata.")] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and constructor metadata.")] - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For(string hostUrl, Refit.RefitSettings? settings) { } public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -1009,10 +957,11 @@ public enum StreamingContentFormat ServerSentEvents = 2, } [System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IJsonTypeInfoContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer +public sealed class SystemTextJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.IJsonTypeInfoContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer { public SystemTextJsonContentSerializer() { } public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } @@ -1022,7 +971,6 @@ public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } public System.Net.Http.HttpContent ToHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } diff --git a/src/Refit/PublicAPI/net462/PublicAPI.txt b/src/Refit/PublicAPI/net462/PublicAPI.txt index ed9468457..42231ea39 100644 --- a/src/Refit/PublicAPI/net462/PublicAPI.txt +++ b/src/Refit/PublicAPI/net462/PublicAPI.txt @@ -155,6 +155,12 @@ public enum CollectionFormat Multi = 5, Indexed = 6, } +public enum ContentSerializerNameStyle +{ + SystemTextJson = 0, + Newtonsoft = 1, + Xml = 2, +} [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultApiExceptionFactory { @@ -175,7 +181,7 @@ public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter public void AddFormat(string format) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public virtual string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter @@ -207,15 +213,27 @@ public class FileInfoPart : Refit.MultipartItem [System.Diagnostics.DebuggerDisplay("{Getter}")] public sealed class FormField { - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } + public FormField(System.Func getter, string clrName, Refit.FormFieldNames names, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } public string ClrName { get; } public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } public string? Format { get; } public System.Func Getter { get; } + public Refit.FormFieldNames Names { get; } public string? PrefixSegment { get; } public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } + public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter, Refit.ContentSerializerNameStyle nameStyle) { } +} +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly record struct FormFieldNames : System.IEquatable +{ + public FormFieldNames(string? ExplicitName, string? JsonName, string? NewtonsoftName, string? XmlName) { } + public string? ExplicitName { get; init; } + public string? JsonName { get; init; } + public string? NewtonsoftName { get; init; } + public string? XmlName { get; init; } + public readonly string? ForStyle(Refit.ContentSerializerNameStyle nameStyle) { } } [System.AttributeUsage(System.AttributeTargets.Parameter)] [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -234,7 +252,7 @@ public static class GeneratedPaging public static System.Uri? ToLink(string? link) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } public static readonly Refit.GeneratedParameterAttributeProvider Empty; @@ -261,10 +279,11 @@ public ref struct GeneratedQueryStringBuilder public static class GeneratedRequestRunner { public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } + public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, Refit.IParameterAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } + public static string BuildFormKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? jsonName, string? newtonsoftName, string? xmlName, string? prefixSegment) { } public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } @@ -285,10 +304,10 @@ public static class GeneratedRequestRunner [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static string RequireAbsoluteUrl(object? url) { } public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } @@ -304,7 +323,7 @@ public static class GeneratedRequestRunner public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -437,6 +456,10 @@ public interface IApiResponse : Refit.IApiResponse bool HasContent { get; } bool IsSuccessfulWithContent { get; } } +public interface IContentSerializerNameStyle +{ + Refit.ContentSerializerNameStyle NameStyle { get; } +} public interface IFormUrlEncodedParameterFormatter { string? Format(object? value, string? formatString) { } @@ -444,9 +467,14 @@ public interface IFormUrlEncodedParameterFormatter public interface IHttpContentSerializer { System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } System.Net.Http.HttpContent ToHttpContent(T item) { } } +public interface IParameterAttributeProvider +{ + object[] GetCustomAttributes(bool inherit) { } + object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } + bool IsDefined(System.Type attributeType, bool inherit) { } +} public interface IQueryConverter { void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } @@ -478,7 +506,7 @@ public interface ISynchronousContentSerializer } public interface IUrlParameterFormatter { - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } public interface IUrlParameterKeyFormatter { @@ -491,7 +519,6 @@ public class JsonContentSerializer : Refit.IHttpContentSerializer { public JsonContentSerializer() { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -543,13 +570,6 @@ public sealed class NextLinkOriginPolicy public override string ToString() { } public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} [System.AttributeUsage(System.AttributeTargets.Method)] [System.Diagnostics.DebuggerDisplay("{Method}")] public sealed class OptionsAttribute : Refit.HttpMethodAttribute @@ -644,7 +664,6 @@ public class ProblemDetails public ProblemDetails() { } public string? Detail { get; set; } public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] public System.Collections.Generic.IDictionary Extensions { get; init; } public string? Instance { get; set; } public int Status { get; set; } @@ -798,17 +817,6 @@ public enum RequestBodySerializationMode Buffered = 1, Streamed = 2, } -public static class RequestBuilder -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} public enum RequestCompression { Default = 0, @@ -817,53 +825,9 @@ public enum RequestCompression Brotli = 3, Zstandard = 4, } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} public static class RestService { public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static T For(string hostUrl, Refit.RefitSettings? settings) { } public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -923,17 +887,17 @@ public enum StreamingContentFormat ServerSentEvents = 2, } [System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer +public sealed class SystemTextJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer { public SystemTextJsonContentSerializer() { } public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } public System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } diff --git a/src/Refit/PublicAPI/net470/PublicAPI.txt b/src/Refit/PublicAPI/net470/PublicAPI.txt index ed9468457..42231ea39 100644 --- a/src/Refit/PublicAPI/net470/PublicAPI.txt +++ b/src/Refit/PublicAPI/net470/PublicAPI.txt @@ -155,6 +155,12 @@ public enum CollectionFormat Multi = 5, Indexed = 6, } +public enum ContentSerializerNameStyle +{ + SystemTextJson = 0, + Newtonsoft = 1, + Xml = 2, +} [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultApiExceptionFactory { @@ -175,7 +181,7 @@ public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter public void AddFormat(string format) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public virtual string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter @@ -207,15 +213,27 @@ public class FileInfoPart : Refit.MultipartItem [System.Diagnostics.DebuggerDisplay("{Getter}")] public sealed class FormField { - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } + public FormField(System.Func getter, string clrName, Refit.FormFieldNames names, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } public string ClrName { get; } public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } public string? Format { get; } public System.Func Getter { get; } + public Refit.FormFieldNames Names { get; } public string? PrefixSegment { get; } public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } + public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter, Refit.ContentSerializerNameStyle nameStyle) { } +} +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly record struct FormFieldNames : System.IEquatable +{ + public FormFieldNames(string? ExplicitName, string? JsonName, string? NewtonsoftName, string? XmlName) { } + public string? ExplicitName { get; init; } + public string? JsonName { get; init; } + public string? NewtonsoftName { get; init; } + public string? XmlName { get; init; } + public readonly string? ForStyle(Refit.ContentSerializerNameStyle nameStyle) { } } [System.AttributeUsage(System.AttributeTargets.Parameter)] [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -234,7 +252,7 @@ public static class GeneratedPaging public static System.Uri? ToLink(string? link) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } public static readonly Refit.GeneratedParameterAttributeProvider Empty; @@ -261,10 +279,11 @@ public ref struct GeneratedQueryStringBuilder public static class GeneratedRequestRunner { public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } + public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, Refit.IParameterAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } + public static string BuildFormKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? jsonName, string? newtonsoftName, string? xmlName, string? prefixSegment) { } public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } @@ -285,10 +304,10 @@ public static class GeneratedRequestRunner [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static string RequireAbsoluteUrl(object? url) { } public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } @@ -304,7 +323,7 @@ public static class GeneratedRequestRunner public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -437,6 +456,10 @@ public interface IApiResponse : Refit.IApiResponse bool HasContent { get; } bool IsSuccessfulWithContent { get; } } +public interface IContentSerializerNameStyle +{ + Refit.ContentSerializerNameStyle NameStyle { get; } +} public interface IFormUrlEncodedParameterFormatter { string? Format(object? value, string? formatString) { } @@ -444,9 +467,14 @@ public interface IFormUrlEncodedParameterFormatter public interface IHttpContentSerializer { System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } System.Net.Http.HttpContent ToHttpContent(T item) { } } +public interface IParameterAttributeProvider +{ + object[] GetCustomAttributes(bool inherit) { } + object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } + bool IsDefined(System.Type attributeType, bool inherit) { } +} public interface IQueryConverter { void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } @@ -478,7 +506,7 @@ public interface ISynchronousContentSerializer } public interface IUrlParameterFormatter { - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } public interface IUrlParameterKeyFormatter { @@ -491,7 +519,6 @@ public class JsonContentSerializer : Refit.IHttpContentSerializer { public JsonContentSerializer() { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -543,13 +570,6 @@ public sealed class NextLinkOriginPolicy public override string ToString() { } public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} [System.AttributeUsage(System.AttributeTargets.Method)] [System.Diagnostics.DebuggerDisplay("{Method}")] public sealed class OptionsAttribute : Refit.HttpMethodAttribute @@ -644,7 +664,6 @@ public class ProblemDetails public ProblemDetails() { } public string? Detail { get; set; } public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] public System.Collections.Generic.IDictionary Extensions { get; init; } public string? Instance { get; set; } public int Status { get; set; } @@ -798,17 +817,6 @@ public enum RequestBodySerializationMode Buffered = 1, Streamed = 2, } -public static class RequestBuilder -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} public enum RequestCompression { Default = 0, @@ -817,53 +825,9 @@ public enum RequestCompression Brotli = 3, Zstandard = 4, } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} public static class RestService { public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static T For(string hostUrl, Refit.RefitSettings? settings) { } public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -923,17 +887,17 @@ public enum StreamingContentFormat ServerSentEvents = 2, } [System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer +public sealed class SystemTextJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer { public SystemTextJsonContentSerializer() { } public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } public System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } diff --git a/src/Refit/PublicAPI/net471/PublicAPI.txt b/src/Refit/PublicAPI/net471/PublicAPI.txt index ed9468457..42231ea39 100644 --- a/src/Refit/PublicAPI/net471/PublicAPI.txt +++ b/src/Refit/PublicAPI/net471/PublicAPI.txt @@ -155,6 +155,12 @@ public enum CollectionFormat Multi = 5, Indexed = 6, } +public enum ContentSerializerNameStyle +{ + SystemTextJson = 0, + Newtonsoft = 1, + Xml = 2, +} [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultApiExceptionFactory { @@ -175,7 +181,7 @@ public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter public void AddFormat(string format) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public virtual string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter @@ -207,15 +213,27 @@ public class FileInfoPart : Refit.MultipartItem [System.Diagnostics.DebuggerDisplay("{Getter}")] public sealed class FormField { - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } + public FormField(System.Func getter, string clrName, Refit.FormFieldNames names, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } public string ClrName { get; } public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } public string? Format { get; } public System.Func Getter { get; } + public Refit.FormFieldNames Names { get; } public string? PrefixSegment { get; } public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } + public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter, Refit.ContentSerializerNameStyle nameStyle) { } +} +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly record struct FormFieldNames : System.IEquatable +{ + public FormFieldNames(string? ExplicitName, string? JsonName, string? NewtonsoftName, string? XmlName) { } + public string? ExplicitName { get; init; } + public string? JsonName { get; init; } + public string? NewtonsoftName { get; init; } + public string? XmlName { get; init; } + public readonly string? ForStyle(Refit.ContentSerializerNameStyle nameStyle) { } } [System.AttributeUsage(System.AttributeTargets.Parameter)] [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -234,7 +252,7 @@ public static class GeneratedPaging public static System.Uri? ToLink(string? link) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } public static readonly Refit.GeneratedParameterAttributeProvider Empty; @@ -261,10 +279,11 @@ public ref struct GeneratedQueryStringBuilder public static class GeneratedRequestRunner { public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } + public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, Refit.IParameterAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } + public static string BuildFormKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? jsonName, string? newtonsoftName, string? xmlName, string? prefixSegment) { } public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } @@ -285,10 +304,10 @@ public static class GeneratedRequestRunner [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static string RequireAbsoluteUrl(object? url) { } public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } @@ -304,7 +323,7 @@ public static class GeneratedRequestRunner public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -437,6 +456,10 @@ public interface IApiResponse : Refit.IApiResponse bool HasContent { get; } bool IsSuccessfulWithContent { get; } } +public interface IContentSerializerNameStyle +{ + Refit.ContentSerializerNameStyle NameStyle { get; } +} public interface IFormUrlEncodedParameterFormatter { string? Format(object? value, string? formatString) { } @@ -444,9 +467,14 @@ public interface IFormUrlEncodedParameterFormatter public interface IHttpContentSerializer { System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } System.Net.Http.HttpContent ToHttpContent(T item) { } } +public interface IParameterAttributeProvider +{ + object[] GetCustomAttributes(bool inherit) { } + object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } + bool IsDefined(System.Type attributeType, bool inherit) { } +} public interface IQueryConverter { void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } @@ -478,7 +506,7 @@ public interface ISynchronousContentSerializer } public interface IUrlParameterFormatter { - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } public interface IUrlParameterKeyFormatter { @@ -491,7 +519,6 @@ public class JsonContentSerializer : Refit.IHttpContentSerializer { public JsonContentSerializer() { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -543,13 +570,6 @@ public sealed class NextLinkOriginPolicy public override string ToString() { } public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} [System.AttributeUsage(System.AttributeTargets.Method)] [System.Diagnostics.DebuggerDisplay("{Method}")] public sealed class OptionsAttribute : Refit.HttpMethodAttribute @@ -644,7 +664,6 @@ public class ProblemDetails public ProblemDetails() { } public string? Detail { get; set; } public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] public System.Collections.Generic.IDictionary Extensions { get; init; } public string? Instance { get; set; } public int Status { get; set; } @@ -798,17 +817,6 @@ public enum RequestBodySerializationMode Buffered = 1, Streamed = 2, } -public static class RequestBuilder -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} public enum RequestCompression { Default = 0, @@ -817,53 +825,9 @@ public enum RequestCompression Brotli = 3, Zstandard = 4, } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} public static class RestService { public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static T For(string hostUrl, Refit.RefitSettings? settings) { } public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -923,17 +887,17 @@ public enum StreamingContentFormat ServerSentEvents = 2, } [System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer +public sealed class SystemTextJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer { public SystemTextJsonContentSerializer() { } public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } public System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } diff --git a/src/Refit/PublicAPI/net472/PublicAPI.txt b/src/Refit/PublicAPI/net472/PublicAPI.txt index ed9468457..42231ea39 100644 --- a/src/Refit/PublicAPI/net472/PublicAPI.txt +++ b/src/Refit/PublicAPI/net472/PublicAPI.txt @@ -155,6 +155,12 @@ public enum CollectionFormat Multi = 5, Indexed = 6, } +public enum ContentSerializerNameStyle +{ + SystemTextJson = 0, + Newtonsoft = 1, + Xml = 2, +} [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultApiExceptionFactory { @@ -175,7 +181,7 @@ public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter public void AddFormat(string format) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public virtual string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter @@ -207,15 +213,27 @@ public class FileInfoPart : Refit.MultipartItem [System.Diagnostics.DebuggerDisplay("{Getter}")] public sealed class FormField { - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } + public FormField(System.Func getter, string clrName, Refit.FormFieldNames names, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } public string ClrName { get; } public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } public string? Format { get; } public System.Func Getter { get; } + public Refit.FormFieldNames Names { get; } public string? PrefixSegment { get; } public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } + public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter, Refit.ContentSerializerNameStyle nameStyle) { } +} +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly record struct FormFieldNames : System.IEquatable +{ + public FormFieldNames(string? ExplicitName, string? JsonName, string? NewtonsoftName, string? XmlName) { } + public string? ExplicitName { get; init; } + public string? JsonName { get; init; } + public string? NewtonsoftName { get; init; } + public string? XmlName { get; init; } + public readonly string? ForStyle(Refit.ContentSerializerNameStyle nameStyle) { } } [System.AttributeUsage(System.AttributeTargets.Parameter)] [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -234,7 +252,7 @@ public static class GeneratedPaging public static System.Uri? ToLink(string? link) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } public static readonly Refit.GeneratedParameterAttributeProvider Empty; @@ -261,10 +279,11 @@ public ref struct GeneratedQueryStringBuilder public static class GeneratedRequestRunner { public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } + public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, Refit.IParameterAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } + public static string BuildFormKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? jsonName, string? newtonsoftName, string? xmlName, string? prefixSegment) { } public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } @@ -285,10 +304,10 @@ public static class GeneratedRequestRunner [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static string RequireAbsoluteUrl(object? url) { } public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } @@ -304,7 +323,7 @@ public static class GeneratedRequestRunner public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -437,6 +456,10 @@ public interface IApiResponse : Refit.IApiResponse bool HasContent { get; } bool IsSuccessfulWithContent { get; } } +public interface IContentSerializerNameStyle +{ + Refit.ContentSerializerNameStyle NameStyle { get; } +} public interface IFormUrlEncodedParameterFormatter { string? Format(object? value, string? formatString) { } @@ -444,9 +467,14 @@ public interface IFormUrlEncodedParameterFormatter public interface IHttpContentSerializer { System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } System.Net.Http.HttpContent ToHttpContent(T item) { } } +public interface IParameterAttributeProvider +{ + object[] GetCustomAttributes(bool inherit) { } + object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } + bool IsDefined(System.Type attributeType, bool inherit) { } +} public interface IQueryConverter { void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } @@ -478,7 +506,7 @@ public interface ISynchronousContentSerializer } public interface IUrlParameterFormatter { - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } public interface IUrlParameterKeyFormatter { @@ -491,7 +519,6 @@ public class JsonContentSerializer : Refit.IHttpContentSerializer { public JsonContentSerializer() { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -543,13 +570,6 @@ public sealed class NextLinkOriginPolicy public override string ToString() { } public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} [System.AttributeUsage(System.AttributeTargets.Method)] [System.Diagnostics.DebuggerDisplay("{Method}")] public sealed class OptionsAttribute : Refit.HttpMethodAttribute @@ -644,7 +664,6 @@ public class ProblemDetails public ProblemDetails() { } public string? Detail { get; set; } public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] public System.Collections.Generic.IDictionary Extensions { get; init; } public string? Instance { get; set; } public int Status { get; set; } @@ -798,17 +817,6 @@ public enum RequestBodySerializationMode Buffered = 1, Streamed = 2, } -public static class RequestBuilder -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} public enum RequestCompression { Default = 0, @@ -817,53 +825,9 @@ public enum RequestCompression Brotli = 3, Zstandard = 4, } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} public static class RestService { public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static T For(string hostUrl, Refit.RefitSettings? settings) { } public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -923,17 +887,17 @@ public enum StreamingContentFormat ServerSentEvents = 2, } [System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer +public sealed class SystemTextJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer { public SystemTextJsonContentSerializer() { } public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } public System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } diff --git a/src/Refit/PublicAPI/net48/PublicAPI.txt b/src/Refit/PublicAPI/net48/PublicAPI.txt index ed9468457..42231ea39 100644 --- a/src/Refit/PublicAPI/net48/PublicAPI.txt +++ b/src/Refit/PublicAPI/net48/PublicAPI.txt @@ -155,6 +155,12 @@ public enum CollectionFormat Multi = 5, Indexed = 6, } +public enum ContentSerializerNameStyle +{ + SystemTextJson = 0, + Newtonsoft = 1, + Xml = 2, +} [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultApiExceptionFactory { @@ -175,7 +181,7 @@ public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter public void AddFormat(string format) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public virtual string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter @@ -207,15 +213,27 @@ public class FileInfoPart : Refit.MultipartItem [System.Diagnostics.DebuggerDisplay("{Getter}")] public sealed class FormField { - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } + public FormField(System.Func getter, string clrName, Refit.FormFieldNames names, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } public string ClrName { get; } public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } public string? Format { get; } public System.Func Getter { get; } + public Refit.FormFieldNames Names { get; } public string? PrefixSegment { get; } public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } + public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter, Refit.ContentSerializerNameStyle nameStyle) { } +} +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly record struct FormFieldNames : System.IEquatable +{ + public FormFieldNames(string? ExplicitName, string? JsonName, string? NewtonsoftName, string? XmlName) { } + public string? ExplicitName { get; init; } + public string? JsonName { get; init; } + public string? NewtonsoftName { get; init; } + public string? XmlName { get; init; } + public readonly string? ForStyle(Refit.ContentSerializerNameStyle nameStyle) { } } [System.AttributeUsage(System.AttributeTargets.Parameter)] [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -234,7 +252,7 @@ public static class GeneratedPaging public static System.Uri? ToLink(string? link) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } public static readonly Refit.GeneratedParameterAttributeProvider Empty; @@ -261,10 +279,11 @@ public ref struct GeneratedQueryStringBuilder public static class GeneratedRequestRunner { public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } + public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, Refit.IParameterAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } + public static string BuildFormKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? jsonName, string? newtonsoftName, string? xmlName, string? prefixSegment) { } public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } @@ -285,10 +304,10 @@ public static class GeneratedRequestRunner [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static string RequireAbsoluteUrl(object? url) { } public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } @@ -304,7 +323,7 @@ public static class GeneratedRequestRunner public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -437,6 +456,10 @@ public interface IApiResponse : Refit.IApiResponse bool HasContent { get; } bool IsSuccessfulWithContent { get; } } +public interface IContentSerializerNameStyle +{ + Refit.ContentSerializerNameStyle NameStyle { get; } +} public interface IFormUrlEncodedParameterFormatter { string? Format(object? value, string? formatString) { } @@ -444,9 +467,14 @@ public interface IFormUrlEncodedParameterFormatter public interface IHttpContentSerializer { System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } System.Net.Http.HttpContent ToHttpContent(T item) { } } +public interface IParameterAttributeProvider +{ + object[] GetCustomAttributes(bool inherit) { } + object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } + bool IsDefined(System.Type attributeType, bool inherit) { } +} public interface IQueryConverter { void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } @@ -478,7 +506,7 @@ public interface ISynchronousContentSerializer } public interface IUrlParameterFormatter { - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } public interface IUrlParameterKeyFormatter { @@ -491,7 +519,6 @@ public class JsonContentSerializer : Refit.IHttpContentSerializer { public JsonContentSerializer() { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -543,13 +570,6 @@ public sealed class NextLinkOriginPolicy public override string ToString() { } public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} [System.AttributeUsage(System.AttributeTargets.Method)] [System.Diagnostics.DebuggerDisplay("{Method}")] public sealed class OptionsAttribute : Refit.HttpMethodAttribute @@ -644,7 +664,6 @@ public class ProblemDetails public ProblemDetails() { } public string? Detail { get; set; } public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] public System.Collections.Generic.IDictionary Extensions { get; init; } public string? Instance { get; set; } public int Status { get; set; } @@ -798,17 +817,6 @@ public enum RequestBodySerializationMode Buffered = 1, Streamed = 2, } -public static class RequestBuilder -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} public enum RequestCompression { Default = 0, @@ -817,53 +825,9 @@ public enum RequestCompression Brotli = 3, Zstandard = 4, } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} public static class RestService { public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static T For(string hostUrl, Refit.RefitSettings? settings) { } public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -923,17 +887,17 @@ public enum StreamingContentFormat ServerSentEvents = 2, } [System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer +public sealed class SystemTextJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer { public SystemTextJsonContentSerializer() { } public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } public System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } diff --git a/src/Refit/PublicAPI/net481/PublicAPI.txt b/src/Refit/PublicAPI/net481/PublicAPI.txt index ed9468457..42231ea39 100644 --- a/src/Refit/PublicAPI/net481/PublicAPI.txt +++ b/src/Refit/PublicAPI/net481/PublicAPI.txt @@ -155,6 +155,12 @@ public enum CollectionFormat Multi = 5, Indexed = 6, } +public enum ContentSerializerNameStyle +{ + SystemTextJson = 0, + Newtonsoft = 1, + Xml = 2, +} [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultApiExceptionFactory { @@ -175,7 +181,7 @@ public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter public void AddFormat(string format) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public virtual string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter @@ -207,15 +213,27 @@ public class FileInfoPart : Refit.MultipartItem [System.Diagnostics.DebuggerDisplay("{Getter}")] public sealed class FormField { - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } + public FormField(System.Func getter, string clrName, Refit.FormFieldNames names, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } public string ClrName { get; } public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } public string? Format { get; } public System.Func Getter { get; } + public Refit.FormFieldNames Names { get; } public string? PrefixSegment { get; } public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } + public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter, Refit.ContentSerializerNameStyle nameStyle) { } +} +[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] +[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] +[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] +public readonly record struct FormFieldNames : System.IEquatable +{ + public FormFieldNames(string? ExplicitName, string? JsonName, string? NewtonsoftName, string? XmlName) { } + public string? ExplicitName { get; init; } + public string? JsonName { get; init; } + public string? NewtonsoftName { get; init; } + public string? XmlName { get; init; } + public readonly string? ForStyle(Refit.ContentSerializerNameStyle nameStyle) { } } [System.AttributeUsage(System.AttributeTargets.Parameter)] [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -234,7 +252,7 @@ public static class GeneratedPaging public static System.Uri? ToLink(string? link) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } public static readonly Refit.GeneratedParameterAttributeProvider Empty; @@ -261,10 +279,11 @@ public ref struct GeneratedQueryStringBuilder public static class GeneratedRequestRunner { public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } + public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, Refit.IParameterAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } + public static string BuildFormKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? jsonName, string? newtonsoftName, string? xmlName, string? prefixSegment) { } public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } @@ -285,10 +304,10 @@ public static class GeneratedRequestRunner [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static string RequireAbsoluteUrl(object? url) { } public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } @@ -304,7 +323,7 @@ public static class GeneratedRequestRunner public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider +public sealed class GeneratedSingleTypeParameterAttributeProvider : Refit.IParameterAttributeProvider { public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -437,6 +456,10 @@ public interface IApiResponse : Refit.IApiResponse bool HasContent { get; } bool IsSuccessfulWithContent { get; } } +public interface IContentSerializerNameStyle +{ + Refit.ContentSerializerNameStyle NameStyle { get; } +} public interface IFormUrlEncodedParameterFormatter { string? Format(object? value, string? formatString) { } @@ -444,9 +467,14 @@ public interface IFormUrlEncodedParameterFormatter public interface IHttpContentSerializer { System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } System.Net.Http.HttpContent ToHttpContent(T item) { } } +public interface IParameterAttributeProvider +{ + object[] GetCustomAttributes(bool inherit) { } + object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } + bool IsDefined(System.Type attributeType, bool inherit) { } +} public interface IQueryConverter { void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } @@ -478,7 +506,7 @@ public interface ISynchronousContentSerializer } public interface IUrlParameterFormatter { - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } + string? Format(object? value, Refit.IParameterAttributeProvider attributeProvider, System.Type type) { } } public interface IUrlParameterKeyFormatter { @@ -491,7 +519,6 @@ public class JsonContentSerializer : Refit.IHttpContentSerializer { public JsonContentSerializer() { } public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } } [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] @@ -543,13 +570,6 @@ public sealed class NextLinkOriginPolicy public override string ToString() { } public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} [System.AttributeUsage(System.AttributeTargets.Method)] [System.Diagnostics.DebuggerDisplay("{Method}")] public sealed class OptionsAttribute : Refit.HttpMethodAttribute @@ -644,7 +664,6 @@ public class ProblemDetails public ProblemDetails() { } public string? Detail { get; set; } public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] public System.Collections.Generic.IDictionary Extensions { get; init; } public string? Instance { get; set; } public int Status { get; set; } @@ -798,17 +817,6 @@ public enum RequestBodySerializationMode Buffered = 1, Streamed = 2, } -public static class RequestBuilder -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} public enum RequestCompression { Default = 0, @@ -817,53 +825,9 @@ public enum RequestCompression Brotli = 3, Zstandard = 4, } -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} public static class RestService { public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - public static T For(string hostUrl, Refit.RefitSettings? settings) { } public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] @@ -923,17 +887,17 @@ public enum StreamingContentFormat ServerSentEvents = 2, } [System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer +public sealed class SystemTextJsonContentSerializer : Refit.IContentSerializerNameStyle, Refit.IHttpContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer { public SystemTextJsonContentSerializer() { } public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } + public Refit.ContentSerializerNameStyle NameStyle { get; } public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public T? DeserializeFromString(string content) { } public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } public System.Net.Http.HttpContent ToHttpContent(T item) { } public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } public System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } diff --git a/src/Refit/PublicAPI/net8.0/PublicAPI.txt b/src/Refit/PublicAPI/net8.0/PublicAPI.txt deleted file mode 100644 index 68fc6e5d3..000000000 --- a/src/Refit/PublicAPI/net8.0/PublicAPI.txt +++ /dev/null @@ -1,1067 +0,0 @@ -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection")] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] -namespace Refit; - -[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{Name}")] -public sealed class AliasAsAttribute : System.Attribute -{ - public AliasAsAttribute(string name) { } - public string Name { get; } -} -[System.Diagnostics.DebuggerDisplay("{StatusCode}")] -public class ApiException : Refit.ApiExceptionBase -{ - protected ApiException(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings) { } - protected ApiException(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings, System.Exception? innerException) { } - protected ApiException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings) { } - protected ApiException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings, System.Exception? innerException) { } - public string? Content { get; set; } - public System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; protected set; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - public bool HasContent { get; } - public System.Net.Http.Headers.HttpResponseHeaders Headers { get; } - public string? ReasonPhrase { get; } - public System.Net.HttpStatusCode StatusCode { get; } - public T? GetContentAs() { } - public System.Threading.Tasks.Task GetContentAsAsync() { } - public bool TryGetContentAs(out T? content) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.Threading.Tasks.Task Create(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings) { } - public static System.Threading.Tasks.Task Create(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings, System.Exception? innerException) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.Threading.Tasks.Task Create(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings) { } - public static System.Threading.Tasks.Task Create(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings, System.Exception? innerException) { } -} -[System.Diagnostics.DebuggerDisplay("{HttpMethod}")] -public abstract class ApiExceptionBase : System.Exception -{ - protected ApiExceptionBase(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings, System.Exception innerException) { } - protected ApiExceptionBase(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings) { } - protected ApiExceptionBase(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings, System.Exception? innerException) { } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "RequestContent")] - public bool HasRequestContent { get; } - public System.Net.Http.HttpMethod HttpMethod { get; } - public Refit.RefitSettings RefitSettings { get; } - public string? RequestContent { get; set; } - public System.Net.Http.HttpRequestMessage RequestMessage { get; } - public System.Uri? Uri { get; } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ApiRequestException : Refit.ApiExceptionBase -{ - public ApiRequestException(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings, System.Exception innerException) { } - public ApiRequestException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings) { } - public ApiRequestException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings, System.Exception? innerException) { } -} -[System.Diagnostics.DebuggerDisplay("ApiResponse: {StatusCode}, Content = {Content}")] -public sealed class ApiResponse : Refit.IApiResponse -{ - public ApiResponse(System.Net.Http.HttpResponseMessage response, T? content, Refit.RefitSettings settings) { } - public ApiResponse(System.Net.Http.HttpResponseMessage response, T? content, Refit.RefitSettings settings, Refit.ApiExceptionBase? error) { } - public ApiResponse(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpResponseMessage? response, T? content, Refit.RefitSettings settings, Refit.ApiExceptionBase? error = null) { } - public T? Content { get; } - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - public System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; } - public Refit.ApiExceptionBase? Error { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - public bool HasContent { get; } - public System.Net.Http.Headers.HttpResponseHeaders? Headers { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - public bool IsReceived { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - public bool IsSuccessStatusCode { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - public bool IsSuccessful { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - public bool IsSuccessfulWithContent { get; } - public string? ReasonPhrase { get; } - public System.Net.Http.HttpRequestMessage RequestMessage { get; } - public Refit.RefitSettings Settings { get; } - public System.Net.HttpStatusCode? StatusCode { get; } - public System.Version? Version { get; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void Dispose() { } - public System.Threading.Tasks.ValueTask> EnsureSuccessStatusCodeAsync() { } - public System.Threading.Tasks.ValueTask> EnsureSuccessfulAsync() { } - public bool HasRequestError(out Refit.ApiRequestException? error) { } - public bool HasResponseError(out Refit.ApiException? error) { } -} -public static class ApiResponseExtensions -{ - extension(Refit.IApiResponse response) - { - public System.Threading.Tasks.ValueTask EnsureSuccessStatusCodeAsync() { } - public System.Threading.Tasks.ValueTask EnsureSuccessfulAsync() { } - public System.Uri? GetLink(string relation) { } - } - extension(Refit.IApiResponse response) - { - public System.Threading.Tasks.ValueTask> EnsureSuccessStatusCodeAsync() { } - public System.Threading.Tasks.ValueTask> EnsureSuccessfulAsync() { } - } -} -[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{Name}")] -[System.Obsolete("Use Refit.StreamPart, Refit.ByteArrayPart, Refit.FileInfoPart or if necessary, inherit from Refit.MultipartItem", false)] -public sealed class AttachmentNameAttribute : System.Attribute -{ - public AttachmentNameAttribute(string name) { } - public string Name { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{Scheme}")] -public sealed class AuthorizeAttribute : System.Attribute -{ - public AuthorizeAttribute(string scheme = "Bearer") { } - public string Scheme { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("Body: Buffered = {Buffered}")] -public sealed class BodyAttribute : System.Attribute -{ - public BodyAttribute() { } - public BodyAttribute(Refit.BodySerializationMethod serializationMethod) { } - public BodyAttribute(bool buffered) { } - public BodyAttribute(Refit.BodySerializationMethod serializationMethod, bool buffered) { } - public bool? Buffered { get; } - public Refit.RequestCompression Compression { get; set; } - public System.IO.Compression.CompressionLevel CompressionLevel { get; set; } - public Refit.BodySerializationMethod SerializationMethod { get; } -} -public enum BodySerializationMethod -{ - Default = 0, - [System.Obsolete("Use BodySerializationMethod.Serialized instead", false)] - Json = 1, - UrlEncoded = 2, - Serialized = 3, - JsonLines = 4, -} -[System.Diagnostics.DebuggerDisplay("{Value}")] -public class ByteArrayPart : Refit.MultipartItem -{ - public ByteArrayPart(byte[] value, string fileName, string? contentType = null, string? name = null) { } - public byte[] Value { get; } - protected override System.Net.Http.HttpContent CreateContent() { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class CamelCaseUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter -{ - public CamelCaseUrlParameterKeyFormatter() { } - public string Format(string key) { } -} -public enum CollectionFormat -{ - RefitParameterFormatter = 0, - Csv = 1, - Ssv = 2, - Tsv = 3, - Pipes = 4, - Multi = 5, - Indexed = 6, -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class DefaultApiExceptionFactory -{ - public DefaultApiExceptionFactory(Refit.RefitSettings refitSettings) { } - public System.Threading.Tasks.ValueTask CreateAsync(System.Net.Http.HttpResponseMessage responseMessage) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class DefaultFormUrlEncodedParameterFormatter : Refit.IFormUrlEncodedParameterFormatter -{ - public DefaultFormUrlEncodedParameterFormatter() { } - public virtual string? Format(object? value, string? formatString) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter -{ - public DefaultUrlParameterFormatter() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void AddFormat(string format) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter -{ - public DefaultUrlParameterKeyFormatter() { } - public virtual string Format(string key) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class DeleteAttribute : Refit.HttpMethodAttribute -{ - public DeleteAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class EncodedAttribute : System.Attribute -{ - public EncodedAttribute() { } -} -[System.Diagnostics.DebuggerDisplay("{Value}")] -public class FileInfoPart : Refit.MultipartItem -{ - public FileInfoPart(System.IO.FileInfo value, string fileName, string? contentType = null, string? name = null) { } - public System.IO.FileInfo Value { get; } - protected override System.Net.Http.HttpContent CreateContent() { } -} -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -[System.Diagnostics.DebuggerDisplay("{Getter}")] -public sealed class FormField -{ - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } - public string ClrName { get; } - public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } - public string? Format { get; } - public System.Func Getter { get; } - public string? PrefixSegment { get; } - public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class FormObjectAttribute : System.Attribute -{ - public FormObjectAttribute() { } -} -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -public static class GeneratedPaging -{ - public static string? HeaderValue(Refit.IApiResponse response, string name) { } - public static System.Uri? NextLink(Refit.IApiResponse response, string headerName) { } - public static Refit.PageContinuation NextOffset(int offset, System.Collections.Generic.IEnumerable? items, long? total) { } - public static Refit.PageContinuation NextValue(TToken? next) where TToken : struct { } - public static Refit.NextLinkOriginPolicy SameOrigin(System.Net.Http.HttpClient client) { } - public static System.Uri? ToLink(string? link) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider -{ - public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } - public static readonly Refit.GeneratedParameterAttributeProvider Empty; - public object[] GetCustomAttributes(bool inherit) { } - public object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public bool IsDefined(System.Type attributeType, bool inherit) { } -} -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public ref struct GeneratedQueryStringBuilder -{ - public GeneratedQueryStringBuilder(string relativePath) { } - public GeneratedQueryStringBuilder(string relativePath, bool hasQuery) { } - public void Add(string name, string? value, bool preEncoded) { } - public void AddCollectionValue(string? value) { } - public void AddCollectionValueFormatted(T value) where T : System.ISpanFormattable { } - public void AddFlag(string? name, bool preEncoded) { } - public void AddFormatted(string name, T value, string? format, bool preEncoded) where T : System.ISpanFormattable { } - public void AddFormattedPreEscapedKey(string name, T value, string? format, bool preEncoded) where T : System.ISpanFormattable { } - public void AddPreEscapedKey(string name, string? value, bool preEncoded) { } - public void BeginCollection(string name, Refit.CollectionFormat collectionFormat, bool preEncoded) { } - public string Build() { } - public void EndCollection() { } -} -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -public static class GeneratedRequestRunner -{ - public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } - public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } - public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } - public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } - public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter) { } - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter, System.ReadOnlySpan<((int StartIdx, int EndIdx) Range, string? Value)> uriParams) { } - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter, System.ReadOnlySpan<((int StartIdx, int EndIdx) Range, string? Value, bool PreEncoded)> uriParams) { } - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter, (int StartIdx, int EndIdx) range, T value) where T : System.ISpanFormattable { } - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter, (int StartIdx, int EndIdx) range, T value, string? format) where T : System.ISpanFormattable { } - public static bool CanUnrollForm(object? body) { } - public static System.Net.Http.HttpContent CompressBodyContent(System.Net.Http.HttpContent content, Refit.RefitSettings settings, Refit.RequestCompression compression, System.IO.Compression.CompressionLevel level) { } - public static System.Net.Http.HttpContent CreateAsyncJsonLinesBodyContent(Refit.RefitSettings settings, System.Collections.Generic.IAsyncEnumerable? body) { } - public static System.Net.Http.HttpContent CreateBodyContent(Refit.RefitSettings settings, TBody body, Refit.BodySerializationMethod serializationMethod, bool streamBody) { } - public static System.Net.Http.HttpContent CreateBodyContent(Refit.RefitSettings settings, TBody body, System.Text.Json.Serialization.Metadata.JsonTypeInfo? typeInfo, Refit.BodySerializationMethod serializationMethod, bool streamBody) { } - public static System.Net.Http.HttpContent CreateJsonLinesBodyContent(Refit.RefitSettings settings, TBody body) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.Net.Http.HttpContent CreateStreamContent(System.IO.Stream stream) { } - public static System.Net.Http.HttpContent CreateTypedJsonLinesBodyContent(Refit.RefitSettings settings, System.Collections.Generic.IEnumerable? body) { } - public static System.Net.Http.HttpContent CreateUrlEncodedBodyContent(Refit.RefitSettings settings, TBody body) { } - public static System.Net.Http.HttpContent CreateUrlEncodedBodyContent(Refit.RefitSettings settings, TBody body, Refit.FormField[] fields) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } - public static string RequireAbsoluteUrl(object? url) { } - public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } - public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } - public static System.Threading.Tasks.Task SendVoidAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } - public static System.Net.Http.HttpContent SerializeMultipartPart(Refit.RefitSettings settings, T value, string fieldName) { } - public static void SetHeader(System.Net.Http.HttpRequestMessage request, string name, string? value, bool validateHeaders) { } - public static void SetRequestJsonTypeInfo(System.Net.Http.HttpRequestMessage request, System.Text.Json.Serialization.Metadata.JsonTypeInfo? typeInfo) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static void SetRequestTimeout(System.Net.Http.HttpRequestMessage request, int timeoutMilliseconds) { } - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - public static System.Collections.Generic.IAsyncEnumerable StreamAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Threading.CancellationToken methodCancellationToken, System.Threading.CancellationToken cancellationToken = default) { } - public static bool UsesDefaultFormUrlEncodedParameterFormatting(Refit.RefitSettings settings) { } - public static bool UsesDefaultUrlParameterFormatting(Refit.RefitSettings settings) { } - public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider -{ - public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public object[] GetCustomAttributes(bool inherit) { } - public object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } - public bool IsDefined(System.Type attributeType, bool inherit) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class GetAttribute : Refit.HttpMethodAttribute -{ - public GetAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class HeadAttribute : Refit.HttpMethodAttribute -{ - public HeadAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{Header}")] -public sealed class HeaderAttribute : System.Attribute -{ - public HeaderAttribute(string header) { } - public string Header { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class HeaderCollectionAttribute : System.Attribute -{ - public HeaderCollectionAttribute() { } -} -[System.AttributeUsage(System.AttributeTargets.Method | System.AttributeTargets.Interface)] -[System.Diagnostics.DebuggerDisplay("{Headers}")] -public sealed class HeadersAttribute : System.Attribute -{ - public HeadersAttribute(params string[] headers) { } - public string[] Headers { get; } -} -[System.Diagnostics.DebuggerDisplay("{Method}")] -public abstract class HttpMethodAttribute : System.Attribute -{ - protected HttpMethodAttribute(string path) { } - public abstract System.Net.Http.HttpMethod Method { get; } - public virtual string Path { get; protected set; } -} -public static class HttpRequestMessageOptions -{ - public static string InterfaceType { get; } - public static string MethodArguments { get; } - public static string MethodName { get; } - public static string RelativePathTemplate { get; } - public static string RequestContent { get; } - public static string RestMethodInfo { get; } -} -[System.Diagnostics.DebuggerDisplay("HttpRetryBackoffOptions")] -public sealed class HttpRetryBackoffOptions -{ - public HttpRetryBackoffOptions() { } - public System.TimeSpan BaseDelay { get; set; } - public Refit.RetryJitterMode JitterMode { get; set; } - public double JitterRatio { get; set; } - public System.TimeSpan MaxDelay { get; set; } - public double ServerDelayJitterRatio { get; set; } - public bool UseJitter { get; set; } -} -[System.Diagnostics.DebuggerDisplay("HTTP retry handler")] -public sealed class HttpRetryHandler : System.Net.Http.DelegatingHandler -{ - public HttpRetryHandler() { } - public HttpRetryHandler(Refit.HttpRetryOptions options) { } - protected override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { } -} -[System.Diagnostics.DebuggerDisplay("MaxRetries = {MaxRetries}")] -public sealed class HttpRetryOptions -{ - public HttpRetryOptions() { } - public Refit.HttpRetryBackoffOptions Backoff { get; } - public System.TimeSpan BaseDelay { get; set; } - public System.Func? DelayProvider { get; set; } - public Refit.RetryJitterMode JitterMode { get; set; } - public double JitterRatio { get; set; } - public System.TimeSpan MaxDelay { get; set; } - public int MaxRequestContentBufferSize { get; set; } - public int MaxRetries { get; set; } - public Refit.HttpRetryReplayOptions Replay { get; } - public Refit.HttpRetryResponsesOptions Responses { get; } - public bool RetryHttpRequestExceptions { get; set; } - public bool RetryUnsafeMethods { get; set; } - public double ServerDelayJitterRatio { get; set; } - public System.Func? ShouldRetry { get; set; } - public System.TimeProvider TimeProvider { get; set; } - public bool UseJitter { get; set; } -} -[System.Diagnostics.DebuggerDisplay("HttpRetryReplayOptions")] -public sealed class HttpRetryReplayOptions -{ - public HttpRetryReplayOptions() { } - public int MaxRequestContentBufferSize { get; set; } - public bool RetryHttpRequestExceptions { get; set; } - public bool RetryUnsafeMethods { get; set; } -} -[System.Diagnostics.DebuggerDisplay("HttpRetryResponsesOptions")] -public sealed class HttpRetryResponsesOptions -{ - public HttpRetryResponsesOptions() { } - public System.Func? DelayProvider { get; set; } - public System.Func? ShouldRetry { get; set; } -} -public interface IApiResponse : System.IDisposable -{ - System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; } - Refit.ApiExceptionBase? Error { get; } - System.Net.Http.Headers.HttpResponseHeaders? Headers { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - bool IsReceived { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - bool IsSuccessStatusCode { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - bool IsSuccessful { get; } - string? ReasonPhrase { get; } - System.Net.Http.HttpRequestMessage? RequestMessage { get; } - System.Net.HttpStatusCode? StatusCode { get; } - System.Version? Version { get; } - bool HasRequestError(out Refit.ApiRequestException? error) { } - bool HasResponseError(out Refit.ApiException? error) { } -} -public interface IApiResponse : Refit.IApiResponse -{ - T? Content { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - bool HasContent { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - bool IsSuccessfulWithContent { get; } -} -public interface IFormUrlEncodedParameterFormatter -{ - string? Format(object? value, string? formatString) { } -} -public interface IHttpContentSerializer -{ - System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - System.Net.Http.HttpContent ToHttpContent(T item) { } -} -public interface IJsonTypeInfoContentSerializer -{ - T? DeserializeFromString(string content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - System.Net.Http.HttpContent ToHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - System.Net.Http.HttpContent ToHttpContentSynchronous(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - System.Net.Http.HttpContent ToStreamingHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } -} -public interface IQueryConverter -{ - void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } -} -public interface IRequestBuilder -{ - Refit.RefitSettings Settings { get; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Building request delegates from reflected method metadata requires runtime generic method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building request delegates from reflected method metadata requires generic method metadata to be available at runtime.")] - System.Func BuildRestResultFuncForMethod(string methodName, System.Type[]? parameterTypes = null, System.Type[]? genericArgumentTypes = null) { } -} -public interface IRequestBuilder : Refit.IRequestBuilder -{ -} -public interface IReturnTypeAdapter -{ - TReturn Adapt(System.Func> invoke) { } -} -public interface IStreamingContentSerializer -{ - System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } -} -public interface ISynchronousContentDeserializer -{ - T? DeserializeFromString(string content) { } -} -public interface ISynchronousContentSerializer -{ - System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } - System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } -} -public interface IUrlParameterFormatter -{ - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } -} -public interface IUrlParameterKeyFormatter -{ - string Format(string key) { } -} -[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -[System.Obsolete("Use NewtonsoftJsonContentSerializer in the Refit.Newtonsoft.Json package instead", true)] -public class JsonContentSerializer : Refit.IHttpContentSerializer -{ - public JsonContentSerializer() { } - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - public System.Net.Http.HttpContent ToHttpContent(T item) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class JsonLinesContent : System.Net.Http.HttpContent -{ - public JsonLinesContent(System.Collections.IEnumerable items, Refit.IHttpContentSerializer serializer) { } - public static string JsonLinesMediaType { get; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { } - protected override bool TryComputeLength(out long length) { } -} -[System.Diagnostics.DebuggerDisplay("JsonLinesContent<{typeof(T).Name,nq}>")] -public sealed class JsonLinesContent : System.Net.Http.HttpContent -{ - public JsonLinesContent(System.Collections.Generic.IAsyncEnumerable items, Refit.IHttpContentSerializer serializer) { } - public JsonLinesContent(System.Collections.Generic.IEnumerable items, Refit.IHttpContentSerializer serializer) { } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { } - protected override bool TryComputeLength(out long length) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class KebabCaseUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter -{ - public KebabCaseUrlParameterKeyFormatter() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public string Format(string key) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{BoundaryText}")] -public sealed class MultipartAttribute : System.Attribute -{ - public MultipartAttribute(string boundaryText = "----MyGreatBoundary") { } - public string BoundaryText { get; } -} -[System.Diagnostics.DebuggerDisplay("MultipartItem: {Name}")] -public abstract class MultipartItem -{ - protected MultipartItem(string fileName, string? contentType) { } - protected MultipartItem(string fileName, string? contentType, string? name) { } - public string? ContentType { get; } - public string FileName { get; } - public string? Name { get; } - protected abstract System.Net.Http.HttpContent CreateContent() { } - public System.Net.Http.HttpContent ToContent() { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NextLinkOriginPolicy -{ - public static Refit.NextLinkOriginPolicy Unrestricted { get; } - public bool IsAllowed(System.Uri link) { } - public override string ToString() { } - public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class OptionsAttribute : Refit.HttpMethodAttribute -{ - public OptionsAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -public static class PageContinuation -{ - public static Refit.PageContinuation To(TToken next) { } -} -[System.Diagnostics.DebuggerDisplay("HasNext = {HasNext}, Token = {Token}")] -public readonly record struct PageContinuation : System.IEquatable> -{ - public bool HasNext { get; } - public TToken? Token { get; } - public static Refit.PageContinuation End { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class PageTokenAttribute : System.Attribute -{ - public PageTokenAttribute() { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class PagedAttribute : System.Attribute -{ - public PagedAttribute() { } - public bool AnyOrigin { get; set; } - public string? Items { get; set; } - public string? Next { get; set; } - public string? NextHeader { get; set; } - public string[]? Origins { get; set; } - public bool SameOrigin { get; set; } - public string? Total { get; set; } -} -public static class PagedEnumerable -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.PagedEnumerable Create(System.Func> fetch, System.Func?> items, System.Func> next) { } - public static Refit.PagedEnumerable Create(TToken first, System.Func> fetch, System.Func?> items, System.Func> next) { } - public static Refit.PagedEnumerable FromCursor(System.Func> fetch, System.Func?> items, System.Func nextCursor) { } - public static Refit.PagedEnumerable FromLinks(Refit.NextLinkOriginPolicy originPolicy, System.Func> fetch, System.Func?> items, System.Func nextLink) { } - public static Refit.PagedEnumerable FromOffset(System.Func> fetch, System.Func?> items, System.Func nextOffset) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class PagedEnumerable : System.Collections.Generic.IAsyncEnumerable -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Collections.Generic.IAsyncEnumerable AsPages() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Collections.Generic.IAsyncEnumerator GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.IObservable ToObservable() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.IObservable ToPageObservable() { } - public override string ToString() { } - public Refit.PagedEnumerable WithMaxPages(int pages) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public Refit.PagedEnumerable WithPrefetch() { } -} -public enum ParameterType -{ - Normal = 0, - RoundTripping = 1, -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class PatchAttribute : Refit.HttpMethodAttribute -{ - public PatchAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Interface)] -[System.Diagnostics.DebuggerDisplay("{Prefix}")] -public sealed class PathPrefixAttribute : System.Attribute -{ - public PathPrefixAttribute(string prefix) { } - public string Prefix { get; } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class PostAttribute : Refit.HttpMethodAttribute -{ - public PostAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.Diagnostics.DebuggerDisplay("{Errors}")] -public class ProblemDetails -{ - public ProblemDetails() { } - public string? Detail { get; set; } - public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] - public System.Collections.Generic.IDictionary Extensions { get; init; } - public string? Instance { get; set; } - public int Status { get; set; } - public string? Title { get; set; } - public string? Type { get; set; } -} -[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("Property: {Key}")] -public sealed class PropertyAttribute : System.Attribute -{ - public PropertyAttribute() { } - public PropertyAttribute(string key) { } - public string? Key { get; } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class PutAttribute : Refit.HttpMethodAttribute -{ - public PutAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{TreatAsString}")] -public sealed class QueryAttribute : System.Attribute -{ - public QueryAttribute() { } - public QueryAttribute(Refit.CollectionFormat collectionFormat) { } - public QueryAttribute(string delimiter) { } - public QueryAttribute(string delimiter, string prefix) { } - public QueryAttribute(string delimiter, string prefix, string format) { } - public Refit.CollectionFormat CollectionFormat { get; set; } - public string Delimiter { get; } - public string? Format { get; set; } - public bool IsCollectionFormatSpecified { get; } - public string? Name { get; set; } - public string? Prefix { get; } - public bool SerializeNull { get; set; } - public bool TreatAsString { get; set; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ConverterType}")] -public sealed class QueryConverterAttribute : System.Attribute -{ - public QueryConverterAttribute(System.Type converterType) { } - public System.Type ConverterType { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class QueryNameAttribute : System.Attribute -{ - public QueryNameAttribute() { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{UriFormat}")] -public sealed class QueryUriFormatAttribute : System.Attribute -{ - public QueryUriFormatAttribute(System.UriFormat uriFormat) { } - public System.UriFormat UriFormat { get; } -} -[System.Diagnostics.DebuggerDisplay("RefitExceptionsSettings")] -public sealed class RefitExceptionsSettings -{ - public bool CaptureRequestContent { get; set; } - public System.Func>? DeserializationExceptionFactory { get; set; } - public System.Func> ExceptionFactory { get; set; } - public System.Action? ExceptionRedactor { get; set; } - public int? MaxExceptionContentLength { get; set; } - public System.Func TransportExceptionFactory { get; set; } -} -[System.Diagnostics.DebuggerDisplay("RefitRequestsSettings")] -public sealed class RefitRequestsSettings -{ - public RefitRequestsSettings() { } - public System.Func>? AuthorizationHeaderValueGetter { get; set; } - public bool CaptureMethodArguments { get; set; } - public System.Func? HttpMessageHandlerFactory { get; set; } - public System.Collections.Generic.Dictionary? HttpRequestMessageOptions { get; init; } - public System.Collections.Generic.List ReturnTypeAdapters { get; } - public bool ValidateHeaders { get; set; } - public System.Version Version { get; set; } - public System.Net.Http.HttpVersionPolicy VersionPolicy { get; set; } -} -[System.Diagnostics.DebuggerDisplay("RefitSerializationSettings")] -public sealed class RefitSerializationSettings -{ - public RefitSerializationSettings() { } - public bool Buffered { get; set; } - public Refit.IHttpContentSerializer ContentSerializer { get; set; } - public Refit.IFormUrlEncodedParameterFormatter FormUrlEncodedParameterFormatter { get; set; } - public Refit.RequestBodySerializationMode RequestBodySerialization { get; set; } - public Refit.RequestCompression RequestCompression { get; set; } - public System.IO.Compression.CompressionLevel RequestCompressionLevel { get; set; } -} -[System.Diagnostics.DebuggerDisplay("RefitSettings: AuthorizationHeaderValueGetter = {AuthorizationHeaderValueGetter}")] -public class RefitSettings -{ - public RefitSettings() { } - public RefitSettings(Refit.IHttpContentSerializer contentSerializer) { } - public RefitSettings(Refit.IHttpContentSerializer contentSerializer, Refit.IUrlParameterFormatter? urlParameterFormatter) { } - public RefitSettings(Refit.IHttpContentSerializer contentSerializer, Refit.IUrlParameterFormatter? urlParameterFormatter, Refit.IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter) { } - public RefitSettings(Refit.IHttpContentSerializer contentSerializer, Refit.IUrlParameterFormatter? urlParameterFormatter, Refit.IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter, Refit.IUrlParameterKeyFormatter? urlParameterKeyFormatter) { } - public bool AllowUnmatchedRouteParameters { get; set; } - public System.Func>? AuthorizationHeaderValueGetter { get; set; } - public bool Buffered { get; set; } - public bool CaptureMethodArguments { get; set; } - public bool CaptureRequestContent { get; set; } - public Refit.CollectionFormat CollectionFormat { get; set; } - public Refit.IHttpContentSerializer ContentSerializer { get; set; } - public System.Func>? DeserializationExceptionFactory { get; set; } - public System.Func> ExceptionFactory { get; set; } - public System.Action? ExceptionRedactor { get; set; } - public Refit.RefitExceptionsSettings Exceptions { get; } - public Refit.IFormUrlEncodedParameterFormatter FormUrlEncodedParameterFormatter { get; set; } - public bool HonorContentSerializerPropertyNamesInQuery { get; set; } - public System.Func? HttpMessageHandlerFactory { get; set; } - public System.Collections.Generic.Dictionary? HttpRequestMessageOptions { get; init; } - public int? MaxExceptionContentLength { get; set; } - public Refit.RequestBodySerializationMode RequestBodySerialization { get; set; } - public Refit.RequestCompression RequestCompression { get; set; } - public System.IO.Compression.CompressionLevel RequestCompressionLevel { get; set; } - public Refit.RefitRequestsSettings Requests { get; } - public System.Collections.Generic.IList ReturnTypeAdapters { get; } - public Refit.RefitSerializationSettings Serialization { get; } - public System.Func TransportExceptionFactory { get; set; } - public Refit.RefitUrlSettings Url { get; } - public Refit.IUrlParameterFormatter UrlParameterFormatter { get; set; } - public System.Collections.Generic.IDictionary UrlParameterFormatterMap { get; } - public Refit.IUrlParameterKeyFormatter UrlParameterKeyFormatter { get; set; } - public Refit.UrlResolutionMode UrlResolution { get; set; } - public bool ValidateHeaders { get; set; } - public System.Version Version { get; set; } - public System.Net.Http.HttpVersionPolicy VersionPolicy { get; set; } - public Refit.RefitSettings UseJsonContext(System.Text.Json.Serialization.JsonSerializerContext context) { } - public Refit.RefitSettings UseJsonContext(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.RefitSettings CamelCase() { } - public static Refit.RefitSettings ForJsonContext(System.Text.Json.Serialization.JsonSerializerContext context) { } - public static Refit.RefitSettings ForJsonContext(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.RefitSettings KebabCase() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.RefitSettings SnakeCase() { } -} -[System.Diagnostics.DebuggerDisplay("RefitUrlSettings")] -public sealed class RefitUrlSettings -{ - public RefitUrlSettings() { } - public bool AllowUnmatchedRouteParameters { get; set; } - public Refit.CollectionFormat CollectionFormat { get; set; } - public bool HonorContentSerializerPropertyNamesInQuery { get; set; } - public Refit.IUrlParameterFormatter UrlParameterFormatter { get; set; } - public System.Collections.Generic.Dictionary UrlParameterFormatterMap { get; } - public Refit.IUrlParameterKeyFormatter UrlParameterKeyFormatter { get; set; } - public Refit.UrlResolutionMode UrlResolution { get; set; } -} -public enum RequestBodySerializationMode -{ - Default = 0, - Buffered = 1, - Streamed = 2, -} -public static class RequestBuilder -{ - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} -public enum RequestCompression -{ - Default = 0, - None = 1, - GZip = 2, - Brotli = 3, - Zstandard = 4, -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} -public static class RestService -{ - public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client by Type requires runtime type lookup and constructor metadata.")] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and constructor metadata.")] - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For(string hostUrl, Refit.RefitSettings? settings) { } - public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } - public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T ForGenerated(System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T ForGenerated(string hostUrl) { } - public static T ForGenerated(System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } - public static T ForGenerated(System.Net.Http.HttpClient client, System.Text.Json.Serialization.JsonSerializerContext context) { } - public static T ForGenerated(string hostUrl, Refit.RefitSettings settings) { } - public static T ForGenerated(string hostUrl, System.Text.Json.Serialization.JsonSerializerContext context) { } - public static T ForGenerated(System.Net.Http.HttpClient client, System.Text.Json.Serialization.JsonSerializerContext context, Refit.RefitSettings settings) { } - public static T ForGenerated(System.Net.Http.HttpClient client, System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - public static T ForGenerated(string hostUrl, System.Text.Json.Serialization.JsonSerializerContext context, Refit.RefitSettings settings) { } - public static T ForGenerated(string hostUrl, System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - public static T ForGenerated(System.Net.Http.HttpClient client, System.Text.Json.Serialization.JsonSerializerContext context, Refit.RefitSettings settings, bool allowReflectionFallback) { } - public static T ForGenerated(string hostUrl, System.Text.Json.Serialization.JsonSerializerContext context, Refit.RefitSettings settings, bool allowReflectionFallback) { } - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public static void RegisterGeneratedFactory(System.Type refitInterfaceType, System.Func factory) { } - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public static void RegisterGeneratedFactory(System.Func factory) { } - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public static void RegisterGeneratedSettingsFactory(System.Func factory) { } -} -public static class RetryDelayProviders -{ - public static System.TimeSpan? Aws(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - public static System.TimeSpan? Azure(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - public static System.TimeSpan? GitHub(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - public static System.TimeSpan? Jira(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - public static System.TimeSpan? ReadHeader(System.Net.Http.HttpResponseMessage response, string headerName, Refit.RetryHeaderFormat format, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.TimeSpan? RetryAfter(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } -} -public enum RetryHeaderFormat -{ - Seconds = 0, - Milliseconds = 1, - UnixTimeSeconds = 2, - RetryAfter = 3, - Iso8601Date = 4, -} -public enum RetryJitterMode -{ - Full = 0, - Symmetric = 1, -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class SnakeCaseUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter -{ - public SnakeCaseUrlParameterKeyFormatter() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public string Format(string key) { } -} -[System.Diagnostics.DebuggerDisplay("{Value}")] -public class StreamPart : Refit.MultipartItem -{ - public StreamPart(System.IO.Stream value, string fileName, string? contentType = null, string? name = null) { } - public System.IO.Stream Value { get; } - protected override System.Net.Http.HttpContent CreateContent() { } -} -public enum StreamingContentFormat -{ - JsonArray = 0, - JsonLines = 1, - ServerSentEvents = 2, -} -[System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IJsonTypeInfoContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer -{ - public SystemTextJsonContentSerializer() { } - public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } - public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T? DeserializeFromString(string content) { } - public T? DeserializeFromString(string content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } - public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - public System.Net.Http.HttpContent ToHttpContent(T item) { } - public System.Net.Http.HttpContent ToHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } - public System.Net.Http.HttpContent ToHttpContentSynchronous(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - public System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } - public System.Net.Http.HttpContent ToStreamingHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - public Refit.SystemTextJsonContentSerializer WithContext(System.Text.Json.Serialization.JsonSerializerContext context) { } - public Refit.SystemTextJsonContentSerializer WithContext(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - public static Refit.SystemTextJsonContentSerializer ForContext(System.Text.Json.Serialization.JsonSerializerContext context) { } - public static Refit.SystemTextJsonContentSerializer ForContext(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - public static System.Text.Json.JsonSerializerOptions GetDefaultJsonSerializerOptions() { } - public static System.Text.Json.JsonSerializerOptions GetFastPathJsonSerializerOptions() { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class SystemTextJsonQueryConverter : Refit.IQueryConverter -{ - public SystemTextJsonQueryConverter() { } - public void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Milliseconds}")] -public sealed class TimeoutAttribute : System.Attribute -{ - public TimeoutAttribute(int milliseconds) { } - public int Milliseconds { get; } -} -public static class UniqueName -{ - public static string ForType(System.Type refitInterfaceType) { } - public static string ForType(System.Type refitInterfaceType, object? serviceKey) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string ForType() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string ForType(object? serviceKey) { } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class UrlAttribute : System.Attribute -{ - public UrlAttribute() { } - public bool AllowRelative { get; set; } -} -public enum UrlResolutionMode -{ - RefitLegacy = 0, - Rfc3986 = 1, -} -[System.Diagnostics.DebuggerDisplay("ValidationApiException: {StatusCode}, Content = {Content}")] -public class ValidationApiException : Refit.ApiException -{ - public ValidationApiException(string message) { } - public ValidationApiException(string message, System.Exception innerException) { } - public Refit.ProblemDetails? Content { get; } - public static Refit.ValidationApiException Create(Refit.ApiException exception) { } -} diff --git a/src/Refit/PublicAPI/net9.0/PublicAPI.txt b/src/Refit/PublicAPI/net9.0/PublicAPI.txt deleted file mode 100644 index de17d143b..000000000 --- a/src/Refit/PublicAPI/net9.0/PublicAPI.txt +++ /dev/null @@ -1,1078 +0,0 @@ -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Benchmarks")] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Reflection")] -[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")] -namespace Refit; - -[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{Name}")] -public sealed class AliasAsAttribute : System.Attribute -{ - public AliasAsAttribute(string name) { } - public string Name { get; } -} -[System.Diagnostics.DebuggerDisplay("{StatusCode}")] -public class ApiException : Refit.ApiExceptionBase -{ - protected ApiException(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings) { } - protected ApiException(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings, System.Exception? innerException) { } - protected ApiException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings) { } - protected ApiException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, string? content, System.Net.HttpStatusCode statusCode, string? reasonPhrase, System.Net.Http.Headers.HttpResponseHeaders headers, Refit.RefitSettings refitSettings, System.Exception? innerException) { } - public string? Content { get; set; } - public System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; protected set; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - public bool HasContent { get; } - public System.Net.Http.Headers.HttpResponseHeaders Headers { get; } - public string? ReasonPhrase { get; } - public System.Net.HttpStatusCode StatusCode { get; } - public T? GetContentAs() { } - public System.Threading.Tasks.Task GetContentAsAsync() { } - public bool TryGetContentAs(out T? content) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.Threading.Tasks.Task Create(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings) { } - public static System.Threading.Tasks.Task Create(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings, System.Exception? innerException) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.Threading.Tasks.Task Create(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings) { } - public static System.Threading.Tasks.Task Create(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, System.Net.Http.HttpResponseMessage response, Refit.RefitSettings refitSettings, System.Exception? innerException) { } -} -[System.Diagnostics.DebuggerDisplay("{HttpMethod}")] -public abstract class ApiExceptionBase : System.Exception -{ - protected ApiExceptionBase(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings, System.Exception innerException) { } - protected ApiExceptionBase(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings) { } - protected ApiExceptionBase(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings, System.Exception? innerException) { } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "RequestContent")] - public bool HasRequestContent { get; } - public System.Net.Http.HttpMethod HttpMethod { get; } - public Refit.RefitSettings RefitSettings { get; } - public string? RequestContent { get; set; } - public System.Net.Http.HttpRequestMessage RequestMessage { get; } - public System.Uri? Uri { get; } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ApiRequestException : Refit.ApiExceptionBase -{ - public ApiRequestException(System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings, System.Exception innerException) { } - public ApiRequestException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings) { } - public ApiRequestException(string exceptionMessage, System.Net.Http.HttpRequestMessage message, System.Net.Http.HttpMethod httpMethod, Refit.RefitSettings refitSettings, System.Exception? innerException) { } -} -[System.Diagnostics.DebuggerDisplay("ApiResponse: {StatusCode}, Content = {Content}")] -public sealed class ApiResponse : Refit.IApiResponse -{ - public ApiResponse(System.Net.Http.HttpResponseMessage response, T? content, Refit.RefitSettings settings) { } - public ApiResponse(System.Net.Http.HttpResponseMessage response, T? content, Refit.RefitSettings settings, Refit.ApiExceptionBase? error) { } - public ApiResponse(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpResponseMessage? response, T? content, Refit.RefitSettings settings, Refit.ApiExceptionBase? error = null) { } - public T? Content { get; } - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - public System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; } - public Refit.ApiExceptionBase? Error { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - public bool HasContent { get; } - public System.Net.Http.Headers.HttpResponseHeaders? Headers { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - public bool IsReceived { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - public bool IsSuccessStatusCode { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - public bool IsSuccessful { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - public bool IsSuccessfulWithContent { get; } - public string? ReasonPhrase { get; } - public System.Net.Http.HttpRequestMessage RequestMessage { get; } - public Refit.RefitSettings Settings { get; } - public System.Net.HttpStatusCode? StatusCode { get; } - public System.Version? Version { get; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void Dispose() { } - public System.Threading.Tasks.ValueTask> EnsureSuccessStatusCodeAsync() { } - public System.Threading.Tasks.ValueTask> EnsureSuccessfulAsync() { } - public bool HasRequestError(out Refit.ApiRequestException? error) { } - public bool HasResponseError(out Refit.ApiException? error) { } -} -public static class ApiResponseExtensions -{ - extension(Refit.IApiResponse response) - { - public System.Threading.Tasks.ValueTask EnsureSuccessStatusCodeAsync() { } - public System.Threading.Tasks.ValueTask EnsureSuccessfulAsync() { } - public System.Uri? GetLink(string relation) { } - } - extension(Refit.IApiResponse response) - { - public System.Threading.Tasks.ValueTask> EnsureSuccessStatusCodeAsync() { } - public System.Threading.Tasks.ValueTask> EnsureSuccessfulAsync() { } - } -} -[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{Name}")] -[System.Obsolete("Use Refit.StreamPart, Refit.ByteArrayPart, Refit.FileInfoPart or if necessary, inherit from Refit.MultipartItem", false)] -public sealed class AttachmentNameAttribute : System.Attribute -{ - public AttachmentNameAttribute(string name) { } - public string Name { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{Scheme}")] -public sealed class AuthorizeAttribute : System.Attribute -{ - public AuthorizeAttribute(string scheme = "Bearer") { } - public string Scheme { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("Body: Buffered = {Buffered}")] -public sealed class BodyAttribute : System.Attribute -{ - public BodyAttribute() { } - public BodyAttribute(Refit.BodySerializationMethod serializationMethod) { } - public BodyAttribute(bool buffered) { } - public BodyAttribute(Refit.BodySerializationMethod serializationMethod, bool buffered) { } - public bool? Buffered { get; } - public Refit.RequestCompression Compression { get; set; } - public System.IO.Compression.CompressionLevel CompressionLevel { get; set; } - public Refit.BodySerializationMethod SerializationMethod { get; } -} -public enum BodySerializationMethod -{ - Default = 0, - [System.Obsolete("Use BodySerializationMethod.Serialized instead", false)] - Json = 1, - UrlEncoded = 2, - Serialized = 3, - JsonLines = 4, -} -[System.Diagnostics.DebuggerDisplay("{Value}")] -public class ByteArrayPart : Refit.MultipartItem -{ - public ByteArrayPart(byte[] value, string fileName, string? contentType = null, string? name = null) { } - public byte[] Value { get; } - protected override System.Net.Http.HttpContent CreateContent() { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class CamelCaseUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter -{ - public CamelCaseUrlParameterKeyFormatter() { } - public string Format(string key) { } -} -public enum CollectionFormat -{ - RefitParameterFormatter = 0, - Csv = 1, - Ssv = 2, - Tsv = 3, - Pipes = 4, - Multi = 5, - Indexed = 6, -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class DefaultApiExceptionFactory -{ - public DefaultApiExceptionFactory(Refit.RefitSettings refitSettings) { } - public System.Threading.Tasks.ValueTask CreateAsync(System.Net.Http.HttpResponseMessage responseMessage) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class DefaultFormUrlEncodedParameterFormatter : Refit.IFormUrlEncodedParameterFormatter -{ - public DefaultFormUrlEncodedParameterFormatter() { } - public virtual string? Format(object? value, string? formatString) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class DefaultUrlParameterFormatter : Refit.IUrlParameterFormatter -{ - public DefaultUrlParameterFormatter() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void AddFormat(string format) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public void AddFormat(string format) { } - public virtual string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class DefaultUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter -{ - public DefaultUrlParameterKeyFormatter() { } - public virtual string Format(string key) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class DeleteAttribute : Refit.HttpMethodAttribute -{ - public DeleteAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class EncodedAttribute : System.Attribute -{ - public EncodedAttribute() { } -} -[System.Diagnostics.DebuggerDisplay("{Value}")] -public class FileInfoPart : Refit.MultipartItem -{ - public FileInfoPart(System.IO.FileInfo value, string fileName, string? contentType = null, string? name = null) { } - public System.IO.FileInfo Value { get; } - protected override System.Net.Http.HttpContent CreateContent() { } -} -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -[System.Diagnostics.DebuggerDisplay("{Getter}")] -public sealed class FormField -{ - public FormField(System.Func getter, string clrName, string? explicitName, string? prefixSegment, string? format, Refit.CollectionFormat? collectionFormat, bool serializeNull) { } - public string ClrName { get; } - public Refit.CollectionFormat? CollectionFormat { get; } - public string? ExplicitName { get; } - public string? Format { get; } - public System.Func Getter { get; } - public string? PrefixSegment { get; } - public bool SerializeNull { get; } - public string? ResolveFieldName(Refit.IUrlParameterKeyFormatter urlParameterKeyFormatter) { } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class FormObjectAttribute : System.Attribute -{ - public FormObjectAttribute() { } -} -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -public static class GeneratedPaging -{ - public static string? HeaderValue(Refit.IApiResponse response, string name) { } - public static System.Uri? NextLink(Refit.IApiResponse response, string headerName) { } - public static Refit.PageContinuation NextOffset(int offset, System.Collections.Generic.IEnumerable? items, long? total) { } - public static Refit.PageContinuation NextValue(TToken? next) where TToken : struct { } - public static Refit.NextLinkOriginPolicy SameOrigin(System.Net.Http.HttpClient client) { } - public static System.Uri? ToLink(string? link) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedParameterAttributeProvider : System.Reflection.ICustomAttributeProvider -{ - public GeneratedParameterAttributeProvider(System.Collections.Generic.Dictionary attributes) { } - public static readonly Refit.GeneratedParameterAttributeProvider Empty; - public object[] GetCustomAttributes(bool inherit) { } - public object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public bool IsDefined(System.Type attributeType, bool inherit) { } -} -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public ref struct GeneratedQueryStringBuilder -{ - public GeneratedQueryStringBuilder(string relativePath) { } - public GeneratedQueryStringBuilder(string relativePath, bool hasQuery) { } - public void Add(string name, string? value, bool preEncoded) { } - public void AddCollectionValue(string? value) { } - public void AddCollectionValueFormatted(T value) where T : System.ISpanFormattable { } - public void AddFlag(string? name, bool preEncoded) { } - public void AddFormatted(string name, T value, string? format, bool preEncoded) where T : System.ISpanFormattable { } - public void AddFormattedPreEscapedKey(string name, T value, string? format, bool preEncoded) where T : System.ISpanFormattable { } - public void AddPreEscapedKey(string name, string? value, bool preEncoded) { } - public void BeginCollection(string name, Refit.CollectionFormat collectionFormat, bool preEncoded) { } - public string Build() { } - public void EndCollection() { } -} -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -public static class GeneratedRequestRunner -{ - public static void AddConfiguredRequestOptions(System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Type interfaceType) { } - public static void AddFormattedCollectionProperty(ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings, System.Collections.IEnumerable? values, string key, Refit.CollectionFormat collectionFormat, bool preEncoded, (System.Type ElementProviderType, System.Reflection.ICustomAttributeProvider JoinedProvider, System.Type JoinedType) formatting) { } - public static void AddHeaderCollection(System.Net.Http.HttpRequestMessage request, System.Collections.Generic.IDictionary? headers, bool validateHeaders) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static void AddRequestProperty(System.Net.Http.HttpRequestMessage request, string key, TValue value) { } - public static string BuildQueryKey(Refit.RefitSettings settings, string clrName, string? explicitName, string? prefixSegment) { } - public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution) { } - public static System.Uri BuildRelativeUri(System.Net.Http.HttpClient client, string relativePath, Refit.UrlResolutionMode urlResolution, System.UriFormat queryUriFormat) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter) { } - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter, System.ReadOnlySpan<((int StartIdx, int EndIdx) Range, string? Value)> uriParams) { } - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter, System.ReadOnlySpan<((int StartIdx, int EndIdx) Range, string? Value, bool PreEncoded)> uriParams) { } - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter, (int StartIdx, int EndIdx) range, T value) where T : System.ISpanFormattable { } - public static string BuildRequestPath(string relativePathTemplate, bool allowUnmatchedParameter, (int StartIdx, int EndIdx) range, T value, string? format) where T : System.ISpanFormattable { } - public static bool CanUnrollForm(object? body) { } - public static System.Net.Http.HttpContent CompressBodyContent(System.Net.Http.HttpContent content, Refit.RefitSettings settings, Refit.RequestCompression compression, System.IO.Compression.CompressionLevel level) { } - public static System.Net.Http.HttpContent CreateAsyncJsonLinesBodyContent(Refit.RefitSettings settings, System.Collections.Generic.IAsyncEnumerable? body) { } - public static System.Net.Http.HttpContent CreateBodyContent(Refit.RefitSettings settings, TBody body, Refit.BodySerializationMethod serializationMethod, bool streamBody) { } - public static System.Net.Http.HttpContent CreateBodyContent(Refit.RefitSettings settings, TBody body, System.Text.Json.Serialization.Metadata.JsonTypeInfo? typeInfo, Refit.BodySerializationMethod serializationMethod, bool streamBody) { } - public static System.Net.Http.HttpContent CreateJsonLinesBodyContent(Refit.RefitSettings settings, TBody body) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.Net.Http.HttpContent CreateStreamContent(System.IO.Stream stream) { } - public static System.Net.Http.HttpContent CreateTypedJsonLinesBodyContent(Refit.RefitSettings settings, System.Collections.Generic.IEnumerable? body) { } - public static System.Net.Http.HttpContent CreateUrlEncodedBodyContent(Refit.RefitSettings settings, TBody body) { } - public static System.Net.Http.HttpContent CreateUrlEncodedBodyContent(Refit.RefitSettings settings, TBody body, Refit.FormField[] fields) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string FormatInvariant(T value, string? format) where T : System.IFormattable { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string? FormatUrlParameter(Refit.RefitSettings settings, object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } - public static string RequireAbsoluteUrl(object? url) { } - public static string RequireRelativeOrAbsoluteUrl(object? url) { } - public static string RoundTripEscapePath(string? value, Refit.RefitSettings settings, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } - public static System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.IObservable SendObservable(System.Net.Http.HttpClient client, System.Func requestFactory, Refit.RefitSettings settings, bool isApiResponse, bool shouldDisposeResponse, bool bufferBody, System.Threading.CancellationToken methodCancellationToken) { } - public static System.Threading.Tasks.Task SendVoidAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, bool bufferBody, System.Threading.CancellationToken cancellationToken) { } - public static System.Net.Http.HttpContent SerializeMultipartPart(Refit.RefitSettings settings, T value, string fieldName) { } - public static void SetHeader(System.Net.Http.HttpRequestMessage request, string name, string? value, bool validateHeaders) { } - public static void SetRequestJsonTypeInfo(System.Net.Http.HttpRequestMessage request, System.Text.Json.Serialization.Metadata.JsonTypeInfo? typeInfo) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static void SetRequestTimeout(System.Net.Http.HttpRequestMessage request, int timeoutMilliseconds) { } - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - public static System.Collections.Generic.IAsyncEnumerable StreamAsync(System.Net.Http.HttpClient client, System.Net.Http.HttpRequestMessage request, Refit.RefitSettings settings, System.Threading.CancellationToken methodCancellationToken, System.Threading.CancellationToken cancellationToken = default) { } - public static bool UsesDefaultFormUrlEncodedParameterFormatting(Refit.RefitSettings settings) { } - public static bool UsesDefaultUrlParameterFormatting(Refit.RefitSettings settings) { } - public static bool UsesDefaultUrlParameterKeyFormatting(Refit.RefitSettings settings) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class GeneratedSingleTypeParameterAttributeProvider : System.Reflection.ICustomAttributeProvider -{ - public GeneratedSingleTypeParameterAttributeProvider(System.Type type, object[] attributes) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public object[] GetCustomAttributes(bool inherit) { } - public object[] GetCustomAttributes(System.Type attributeType, bool inherit) { } - public bool IsDefined(System.Type attributeType, bool inherit) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class GetAttribute : Refit.HttpMethodAttribute -{ - public GetAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class HeadAttribute : Refit.HttpMethodAttribute -{ - public HeadAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{Header}")] -public sealed class HeaderAttribute : System.Attribute -{ - public HeaderAttribute(string header) { } - public string Header { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class HeaderCollectionAttribute : System.Attribute -{ - public HeaderCollectionAttribute() { } -} -[System.AttributeUsage(System.AttributeTargets.Method | System.AttributeTargets.Interface)] -[System.Diagnostics.DebuggerDisplay("{Headers}")] -public sealed class HeadersAttribute : System.Attribute -{ - public HeadersAttribute(params string[] headers) { } - public string[] Headers { get; } -} -[System.Diagnostics.DebuggerDisplay("{Method}")] -public abstract class HttpMethodAttribute : System.Attribute -{ - protected HttpMethodAttribute(string path) { } - public abstract System.Net.Http.HttpMethod Method { get; } - public virtual string Path { get; protected set; } -} -public static class HttpRequestMessageOptions -{ - public static string InterfaceType { get; } - public static string MethodArguments { get; } - public static string MethodName { get; } - public static string RelativePathTemplate { get; } - public static string RequestContent { get; } - public static string RestMethodInfo { get; } -} -[System.Diagnostics.DebuggerDisplay("HttpRetryBackoffOptions")] -public sealed class HttpRetryBackoffOptions -{ - public HttpRetryBackoffOptions() { } - public System.TimeSpan BaseDelay { get; set; } - public Refit.RetryJitterMode JitterMode { get; set; } - public double JitterRatio { get; set; } - public System.TimeSpan MaxDelay { get; set; } - public double ServerDelayJitterRatio { get; set; } - public bool UseJitter { get; set; } -} -[System.Diagnostics.DebuggerDisplay("HTTP retry handler")] -public sealed class HttpRetryHandler : System.Net.Http.DelegatingHandler -{ - public HttpRetryHandler() { } - public HttpRetryHandler(Refit.HttpRetryOptions options) { } - protected override System.Threading.Tasks.Task SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) { } -} -[System.Diagnostics.DebuggerDisplay("MaxRetries = {MaxRetries}")] -public sealed class HttpRetryOptions -{ - public HttpRetryOptions() { } - public Refit.HttpRetryBackoffOptions Backoff { get; } - public System.TimeSpan BaseDelay { get; set; } - public System.Func? DelayProvider { get; set; } - public Refit.RetryJitterMode JitterMode { get; set; } - public double JitterRatio { get; set; } - public System.TimeSpan MaxDelay { get; set; } - public int MaxRequestContentBufferSize { get; set; } - public int MaxRetries { get; set; } - public Refit.HttpRetryReplayOptions Replay { get; } - public Refit.HttpRetryResponsesOptions Responses { get; } - public bool RetryHttpRequestExceptions { get; set; } - public bool RetryUnsafeMethods { get; set; } - public double ServerDelayJitterRatio { get; set; } - public System.Func? ShouldRetry { get; set; } - public System.TimeProvider TimeProvider { get; set; } - public bool UseJitter { get; set; } -} -[System.Diagnostics.DebuggerDisplay("HttpRetryReplayOptions")] -public sealed class HttpRetryReplayOptions -{ - public HttpRetryReplayOptions() { } - public int MaxRequestContentBufferSize { get; set; } - public bool RetryHttpRequestExceptions { get; set; } - public bool RetryUnsafeMethods { get; set; } -} -[System.Diagnostics.DebuggerDisplay("HttpRetryResponsesOptions")] -public sealed class HttpRetryResponsesOptions -{ - public HttpRetryResponsesOptions() { } - public System.Func? DelayProvider { get; set; } - public System.Func? ShouldRetry { get; set; } -} -public interface IApiResponse : System.IDisposable -{ - System.Net.Http.Headers.HttpContentHeaders? ContentHeaders { get; } - Refit.ApiExceptionBase? Error { get; } - System.Net.Http.Headers.HttpResponseHeaders? Headers { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - bool IsReceived { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - bool IsSuccessStatusCode { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Headers")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "StatusCode")] - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Version")] - bool IsSuccessful { get; } - string? ReasonPhrase { get; } - System.Net.Http.HttpRequestMessage? RequestMessage { get; } - System.Net.HttpStatusCode? StatusCode { get; } - System.Version? Version { get; } - bool HasRequestError(out Refit.ApiRequestException? error) { } - bool HasResponseError(out Refit.ApiException? error) { } -} -public interface IApiResponse : Refit.IApiResponse -{ - T? Content { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - bool HasContent { get; } - [System.Diagnostics.CodeAnalysis.MemberNotNullWhen(true, "Content")] - bool IsSuccessfulWithContent { get; } -} -public interface IFormUrlEncodedParameterFormatter -{ - string? Format(object? value, string? formatString) { } -} -public interface IHttpContentSerializer -{ - System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - System.Net.Http.HttpContent ToHttpContent(T item) { } -} -public interface IJsonTypeInfoContentSerializer -{ - T? DeserializeFromString(string content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - System.Net.Http.HttpContent ToHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - System.Net.Http.HttpContent ToHttpContentSynchronous(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - System.Net.Http.HttpContent ToStreamingHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } -} -public interface IQueryConverter -{ - void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } -} -public interface IRequestBuilder -{ - Refit.RefitSettings Settings { get; } - [System.Diagnostics.CodeAnalysis.RequiresDynamicCode("Building request delegates from reflected method metadata requires runtime generic method instantiation.")] - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building request delegates from reflected method metadata requires generic method metadata to be available at runtime.")] - System.Func BuildRestResultFuncForMethod(string methodName, System.Type[]? parameterTypes = null, System.Type[]? genericArgumentTypes = null) { } -} -public interface IRequestBuilder : Refit.IRequestBuilder -{ -} -public interface IReturnTypeAdapter -{ - TReturn Adapt(System.Func> invoke) { } -} -public interface IStreamingContentSerializer -{ - System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } -} -public interface ISynchronousContentDeserializer -{ - T? DeserializeFromString(string content) { } -} -public interface ISynchronousContentSerializer -{ - System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } - System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } -} -public interface IUrlParameterFormatter -{ - string? Format(object? value, System.Reflection.ICustomAttributeProvider attributeProvider, System.Type type) { } -} -public interface IUrlParameterKeyFormatter -{ - string Format(string key) { } -} -[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -[System.Obsolete("Use NewtonsoftJsonContentSerializer in the Refit.Newtonsoft.Json package instead", true)] -public class JsonContentSerializer : Refit.IHttpContentSerializer -{ - public JsonContentSerializer() { } - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public string GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - public System.Net.Http.HttpContent ToHttpContent(T item) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class JsonLinesContent : System.Net.Http.HttpContent -{ - public JsonLinesContent(System.Collections.IEnumerable items, Refit.IHttpContentSerializer serializer) { } - public static string JsonLinesMediaType { get; } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { } - protected override bool TryComputeLength(out long length) { } -} -[System.Diagnostics.DebuggerDisplay("JsonLinesContent<{typeof(T).Name,nq}>")] -public sealed class JsonLinesContent : System.Net.Http.HttpContent -{ - public JsonLinesContent(System.Collections.Generic.IAsyncEnumerable items, Refit.IHttpContentSerializer serializer) { } - public JsonLinesContent(System.Collections.Generic.IEnumerable items, Refit.IHttpContentSerializer serializer) { } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context) { } - protected override System.Threading.Tasks.Task SerializeToStreamAsync(System.IO.Stream stream, System.Net.TransportContext? context, System.Threading.CancellationToken cancellationToken) { } - protected override bool TryComputeLength(out long length) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class KebabCaseUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter -{ - public KebabCaseUrlParameterKeyFormatter() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public string Format(string key) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{BoundaryText}")] -public sealed class MultipartAttribute : System.Attribute -{ - public MultipartAttribute(string boundaryText = "----MyGreatBoundary") { } - public string BoundaryText { get; } -} -[System.Diagnostics.DebuggerDisplay("MultipartItem: {Name}")] -public abstract class MultipartItem -{ - protected MultipartItem(string fileName, string? contentType) { } - protected MultipartItem(string fileName, string? contentType, string? name) { } - public string? ContentType { get; } - public string FileName { get; } - public string? Name { get; } - protected abstract System.Net.Http.HttpContent CreateContent() { } - public System.Net.Http.HttpContent ToContent() { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class NextLinkOriginPolicy -{ - public static Refit.NextLinkOriginPolicy Unrestricted { get; } - public bool IsAllowed(System.Uri link) { } - public override string ToString() { } - public static Refit.NextLinkOriginPolicy Allow(params System.Uri[] origins) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class ObjectToInferredTypesConverter : System.Text.Json.Serialization.JsonConverter -{ - public ObjectToInferredTypesConverter() { } - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options) { } - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class OptionsAttribute : Refit.HttpMethodAttribute -{ - public OptionsAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -public static class PageContinuation -{ - public static Refit.PageContinuation To(TToken next) { } -} -[System.Diagnostics.DebuggerDisplay("HasNext = {HasNext}, Token = {Token}")] -public readonly record struct PageContinuation : System.IEquatable> -{ - public bool HasNext { get; } - public TToken? Token { get; } - public static Refit.PageContinuation End { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class PageTokenAttribute : System.Attribute -{ - public PageTokenAttribute() { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class PagedAttribute : System.Attribute -{ - public PagedAttribute() { } - public bool AnyOrigin { get; set; } - public string? Items { get; set; } - public string? Next { get; set; } - public string? NextHeader { get; set; } - public string[]? Origins { get; set; } - public bool SameOrigin { get; set; } - public string? Total { get; set; } -} -public static class PagedEnumerable -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.PagedEnumerable Create(System.Func> fetch, System.Func?> items, System.Func> next) { } - public static Refit.PagedEnumerable Create(TToken first, System.Func> fetch, System.Func?> items, System.Func> next) { } - public static Refit.PagedEnumerable FromCursor(System.Func> fetch, System.Func?> items, System.Func nextCursor) { } - public static Refit.PagedEnumerable FromLinks(Refit.NextLinkOriginPolicy originPolicy, System.Func> fetch, System.Func?> items, System.Func nextLink) { } - public static Refit.PagedEnumerable FromOffset(System.Func> fetch, System.Func?> items, System.Func nextOffset) { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class PagedEnumerable : System.Collections.Generic.IAsyncEnumerable -{ - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Collections.Generic.IAsyncEnumerable AsPages() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Collections.Generic.IAsyncEnumerator GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.IObservable ToObservable() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.IObservable ToPageObservable() { } - public override string ToString() { } - public Refit.PagedEnumerable WithMaxPages(int pages) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public Refit.PagedEnumerable WithPrefetch() { } -} -public enum ParameterType -{ - Normal = 0, - RoundTripping = 1, -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class PatchAttribute : Refit.HttpMethodAttribute -{ - public PatchAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Interface)] -[System.Diagnostics.DebuggerDisplay("{Prefix}")] -public sealed class PathPrefixAttribute : System.Attribute -{ - public PathPrefixAttribute(string prefix) { } - public string Prefix { get; } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class PostAttribute : Refit.HttpMethodAttribute -{ - public PostAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.Diagnostics.DebuggerDisplay("{Errors}")] -public class ProblemDetails -{ - public ProblemDetails() { } - public string? Detail { get; set; } - public System.Collections.Generic.Dictionary Errors { get; init; } - [System.Text.Json.Serialization.JsonExtensionData] - public System.Collections.Generic.IDictionary Extensions { get; init; } - public string? Instance { get; set; } - public int Status { get; set; } - public string? Title { get; set; } - public string? Type { get; set; } -} -[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("Property: {Key}")] -public sealed class PropertyAttribute : System.Attribute -{ - public PropertyAttribute() { } - public PropertyAttribute(string key) { } - public string? Key { get; } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Method}")] -public sealed class PutAttribute : Refit.HttpMethodAttribute -{ - public PutAttribute(string path) { } - public override System.Net.Http.HttpMethod Method { get; } -} -[System.AttributeUsage(System.AttributeTargets.Property | System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{TreatAsString}")] -public sealed class QueryAttribute : System.Attribute -{ - public QueryAttribute() { } - public QueryAttribute(Refit.CollectionFormat collectionFormat) { } - public QueryAttribute(string delimiter) { } - public QueryAttribute(string delimiter, string prefix) { } - public QueryAttribute(string delimiter, string prefix, string format) { } - public Refit.CollectionFormat CollectionFormat { get; set; } - public string Delimiter { get; } - public string? Format { get; set; } - public bool IsCollectionFormatSpecified { get; } - public string? Name { get; set; } - public string? Prefix { get; } - public bool SerializeNull { get; set; } - public bool TreatAsString { get; set; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ConverterType}")] -public sealed class QueryConverterAttribute : System.Attribute -{ - public QueryConverterAttribute(System.Type converterType) { } - public System.Type ConverterType { get; } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class QueryNameAttribute : System.Attribute -{ - public QueryNameAttribute() { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{UriFormat}")] -public sealed class QueryUriFormatAttribute : System.Attribute -{ - public QueryUriFormatAttribute(System.UriFormat uriFormat) { } - public System.UriFormat UriFormat { get; } -} -[System.Diagnostics.DebuggerDisplay("RefitExceptionsSettings")] -public sealed class RefitExceptionsSettings -{ - public bool CaptureRequestContent { get; set; } - public System.Func>? DeserializationExceptionFactory { get; set; } - public System.Func> ExceptionFactory { get; set; } - public System.Action? ExceptionRedactor { get; set; } - public int? MaxExceptionContentLength { get; set; } - public System.Func TransportExceptionFactory { get; set; } -} -[System.Diagnostics.DebuggerDisplay("RefitRequestsSettings")] -public sealed class RefitRequestsSettings -{ - public RefitRequestsSettings() { } - public System.Func>? AuthorizationHeaderValueGetter { get; set; } - public bool CaptureMethodArguments { get; set; } - public System.Func? HttpMessageHandlerFactory { get; set; } - public System.Collections.Generic.Dictionary? HttpRequestMessageOptions { get; init; } - public System.Collections.Generic.List ReturnTypeAdapters { get; } - public bool ValidateHeaders { get; set; } - public System.Version Version { get; set; } - public System.Net.Http.HttpVersionPolicy VersionPolicy { get; set; } -} -[System.Diagnostics.DebuggerDisplay("RefitSerializationSettings")] -public sealed class RefitSerializationSettings -{ - public RefitSerializationSettings() { } - public bool Buffered { get; set; } - public Refit.IHttpContentSerializer ContentSerializer { get; set; } - public Refit.IFormUrlEncodedParameterFormatter FormUrlEncodedParameterFormatter { get; set; } - public Refit.RequestBodySerializationMode RequestBodySerialization { get; set; } - public Refit.RequestCompression RequestCompression { get; set; } - public System.IO.Compression.CompressionLevel RequestCompressionLevel { get; set; } - public Refit.RequestCompressionOptions? RequestCompressionOptions { get; set; } -} -[System.Diagnostics.DebuggerDisplay("RefitSettings: AuthorizationHeaderValueGetter = {AuthorizationHeaderValueGetter}")] -public class RefitSettings -{ - public RefitSettings() { } - public RefitSettings(Refit.IHttpContentSerializer contentSerializer) { } - public RefitSettings(Refit.IHttpContentSerializer contentSerializer, Refit.IUrlParameterFormatter? urlParameterFormatter) { } - public RefitSettings(Refit.IHttpContentSerializer contentSerializer, Refit.IUrlParameterFormatter? urlParameterFormatter, Refit.IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter) { } - public RefitSettings(Refit.IHttpContentSerializer contentSerializer, Refit.IUrlParameterFormatter? urlParameterFormatter, Refit.IFormUrlEncodedParameterFormatter? formUrlEncodedParameterFormatter, Refit.IUrlParameterKeyFormatter? urlParameterKeyFormatter) { } - public bool AllowUnmatchedRouteParameters { get; set; } - public System.Func>? AuthorizationHeaderValueGetter { get; set; } - public bool Buffered { get; set; } - public bool CaptureMethodArguments { get; set; } - public bool CaptureRequestContent { get; set; } - public Refit.CollectionFormat CollectionFormat { get; set; } - public Refit.IHttpContentSerializer ContentSerializer { get; set; } - public System.Func>? DeserializationExceptionFactory { get; set; } - public System.Func> ExceptionFactory { get; set; } - public System.Action? ExceptionRedactor { get; set; } - public Refit.RefitExceptionsSettings Exceptions { get; } - public Refit.IFormUrlEncodedParameterFormatter FormUrlEncodedParameterFormatter { get; set; } - public bool HonorContentSerializerPropertyNamesInQuery { get; set; } - public System.Func? HttpMessageHandlerFactory { get; set; } - public System.Collections.Generic.Dictionary? HttpRequestMessageOptions { get; init; } - public int? MaxExceptionContentLength { get; set; } - public Refit.RequestBodySerializationMode RequestBodySerialization { get; set; } - public Refit.RequestCompression RequestCompression { get; set; } - public System.IO.Compression.CompressionLevel RequestCompressionLevel { get; set; } - public Refit.RequestCompressionOptions? RequestCompressionOptions { get; set; } - public Refit.RefitRequestsSettings Requests { get; } - public System.Collections.Generic.IList ReturnTypeAdapters { get; } - public Refit.RefitSerializationSettings Serialization { get; } - public System.Func TransportExceptionFactory { get; set; } - public Refit.RefitUrlSettings Url { get; } - public Refit.IUrlParameterFormatter UrlParameterFormatter { get; set; } - public System.Collections.Generic.IDictionary UrlParameterFormatterMap { get; } - public Refit.IUrlParameterKeyFormatter UrlParameterKeyFormatter { get; set; } - public Refit.UrlResolutionMode UrlResolution { get; set; } - public bool ValidateHeaders { get; set; } - public System.Version Version { get; set; } - public System.Net.Http.HttpVersionPolicy VersionPolicy { get; set; } - public Refit.RefitSettings UseJsonContext(System.Text.Json.Serialization.JsonSerializerContext context) { } - public Refit.RefitSettings UseJsonContext(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.RefitSettings CamelCase() { } - public static Refit.RefitSettings ForJsonContext(System.Text.Json.Serialization.JsonSerializerContext context) { } - public static Refit.RefitSettings ForJsonContext(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.RefitSettings KebabCase() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.RefitSettings SnakeCase() { } -} -[System.Diagnostics.DebuggerDisplay("RefitUrlSettings")] -public sealed class RefitUrlSettings -{ - public RefitUrlSettings() { } - public bool AllowUnmatchedRouteParameters { get; set; } - public Refit.CollectionFormat CollectionFormat { get; set; } - public bool HonorContentSerializerPropertyNamesInQuery { get; set; } - public Refit.IUrlParameterFormatter UrlParameterFormatter { get; set; } - public System.Collections.Generic.Dictionary UrlParameterFormatterMap { get; } - public Refit.IUrlParameterKeyFormatter UrlParameterKeyFormatter { get; set; } - public Refit.UrlResolutionMode UrlResolution { get; set; } -} -public enum RequestBodySerializationMode -{ - Default = 0, - Buffered = 1, - Streamed = 2, -} -public static class RequestBuilder -{ - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType() { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { } -} -public enum RequestCompression -{ - Default = 0, - None = 1, - GZip = 2, - Brotli = 3, - Zstandard = 4, -} -[System.Diagnostics.DebuggerDisplay("{GZip} {Brotli}")] -public sealed class RequestCompressionOptions -{ - public RequestCompressionOptions() { } - public System.IO.Compression.BrotliCompressionOptions? Brotli { get; set; } - public System.IO.Compression.ZLibCompressionOptions? GZip { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public record RestMethodInfo : System.IEquatable -{ - public RestMethodInfo(string Name, System.Type HostingType, System.Reflection.MethodInfo MethodInfo, string RelativePath, System.Type ReturnType) { } - public System.Type HostingType { get; init; } - public System.Reflection.MethodInfo MethodInfo { get; init; } - public string Name { get; init; } - public string RelativePath { get; init; } - public System.Type ReturnType { get; init; } -} -[System.Diagnostics.DebuggerDisplay("RestMethodParameterInfo: {Name}")] -public class RestMethodParameterInfo -{ - public RestMethodParameterInfo(bool isObjectPropertyParameter, System.Reflection.ParameterInfo parameterInfo) { } - public RestMethodParameterInfo(string name, System.Reflection.ParameterInfo parameterInfo) { } - public bool IsObjectPropertyParameter { get; set; } - public string? Name { get; set; } - public System.Reflection.ParameterInfo ParameterInfo { get; set; } - public System.Collections.Generic.List ParameterProperties { get; init; } - public Refit.ParameterType Type { get; set; } -} -[System.Diagnostics.DebuggerDisplay("{Name}")] -public class RestMethodParameterProperty -{ - public RestMethodParameterProperty(string name, System.Collections.Generic.IReadOnlyList propertyChain) { } - public RestMethodParameterProperty(string name, System.Reflection.PropertyInfo propertyInfo) { } - public string Name { get; set; } - public System.Collections.Generic.IReadOnlyList PropertyChain { get; set; } - public System.Reflection.PropertyInfo PropertyInfo { get; set; } -} -public static class RestService -{ - public static System.Net.Http.HttpClient CreateHttpClient(string hostUrl, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static object For(System.Type refitInterfaceType, string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client by Type requires runtime type lookup and constructor metadata.")] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(System.Net.Http.HttpClient client) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T For(string hostUrl) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and constructor metadata.")] - public static T For(System.Net.Http.HttpClient client, Refit.IRequestBuilder builder) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For(System.Net.Http.HttpClient client, Refit.RefitSettings? settings) { } - [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For(string hostUrl, Refit.RefitSettings? settings) { } - public static object ForGenerated(System.Type refitInterfaceType, System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } - public static object ForGenerated(System.Type refitInterfaceType, string hostUrl, Refit.RefitSettings settings) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T ForGenerated(System.Net.Http.HttpClient client) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static T ForGenerated(string hostUrl) { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public static T ForGenerated(System.Net.Http.HttpClient client, Refit.RefitSettings settings) { } - public static T ForGenerated(System.Net.Http.HttpClient client, System.Text.Json.Serialization.JsonSerializerContext context) { } - [System.Runtime.CompilerServices.OverloadResolutionPriority(1)] - public static T ForGenerated(string hostUrl, Refit.RefitSettings settings) { } - public static T ForGenerated(string hostUrl, System.Text.Json.Serialization.JsonSerializerContext context) { } - public static T ForGenerated(System.Net.Http.HttpClient client, System.Text.Json.Serialization.JsonSerializerContext context, Refit.RefitSettings settings) { } - public static T ForGenerated(System.Net.Http.HttpClient client, System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - public static T ForGenerated(string hostUrl, System.Text.Json.Serialization.JsonSerializerContext context, Refit.RefitSettings settings) { } - public static T ForGenerated(string hostUrl, System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - public static T ForGenerated(System.Net.Http.HttpClient client, System.Text.Json.Serialization.JsonSerializerContext context, Refit.RefitSettings settings, bool allowReflectionFallback) { } - public static T ForGenerated(string hostUrl, System.Text.Json.Serialization.JsonSerializerContext context, Refit.RefitSettings settings, bool allowReflectionFallback) { } - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public static void RegisterGeneratedFactory(System.Type refitInterfaceType, System.Func factory) { } - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public static void RegisterGeneratedFactory(System.Func factory) { } - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public static void RegisterGeneratedSettingsFactory(System.Func factory) { } -} -public static class RetryDelayProviders -{ - public static System.TimeSpan? Aws(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - public static System.TimeSpan? Azure(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - public static System.TimeSpan? GitHub(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - public static System.TimeSpan? Jira(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - public static System.TimeSpan? ReadHeader(System.Net.Http.HttpResponseMessage response, string headerName, Refit.RetryHeaderFormat format, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static System.TimeSpan? RetryAfter(System.Net.Http.HttpResponseMessage response, System.DateTimeOffset now, System.Threading.CancellationToken cancellationToken) { } -} -public enum RetryHeaderFormat -{ - Seconds = 0, - Milliseconds = 1, - UnixTimeSeconds = 2, - RetryAfter = 3, - Iso8601Date = 4, -} -public enum RetryJitterMode -{ - Full = 0, - Symmetric = 1, -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public class SnakeCaseUrlParameterKeyFormatter : Refit.IUrlParameterKeyFormatter -{ - public SnakeCaseUrlParameterKeyFormatter() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public string Format(string key) { } -} -[System.Diagnostics.DebuggerDisplay("{Value}")] -public class StreamPart : Refit.MultipartItem -{ - public StreamPart(System.IO.Stream value, string fileName, string? contentType = null, string? name = null) { } - public System.IO.Stream Value { get; } - protected override System.Net.Http.HttpContent CreateContent() { } -} -public enum StreamingContentFormat -{ - JsonArray = 0, - JsonLines = 1, - ServerSentEvents = 2, -} -[System.Diagnostics.DebuggerDisplay("{SerializerOptions}")] -public sealed class SystemTextJsonContentSerializer : Refit.IHttpContentSerializer, Refit.IJsonTypeInfoContentSerializer, Refit.IStreamingContentSerializer, Refit.ISynchronousContentDeserializer, Refit.ISynchronousContentSerializer -{ - public SystemTextJsonContentSerializer() { } - public SystemTextJsonContentSerializer(System.Text.Json.JsonSerializerOptions jsonSerializerOptions) { } - public System.Text.Json.JsonSerializerOptions SerializerOptions { get; } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public T? DeserializeFromString(string content) { } - public T? DeserializeFromString(string content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Threading.CancellationToken cancellationToken = default) { } - public System.Collections.Generic.IAsyncEnumerable DeserializeStreamAsync(System.IO.Stream stream, Refit.StreamingContentFormat format, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Threading.CancellationToken cancellationToken = default) { } - public System.Threading.Tasks.Task FromHttpContentAsync(System.Net.Http.HttpContent content, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo, System.Threading.CancellationToken cancellationToken = default) { } - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) { } - public System.Net.Http.HttpContent ToHttpContent(T item) { } - public System.Net.Http.HttpContent ToHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - public System.Net.Http.HttpContent ToHttpContentSynchronous(T item) { } - public System.Net.Http.HttpContent ToHttpContentSynchronous(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - public System.Net.Http.HttpContent ToStreamingHttpContent(T item) { } - public System.Net.Http.HttpContent ToStreamingHttpContent(T item, System.Text.Json.Serialization.Metadata.JsonTypeInfo typeInfo) { } - public Refit.SystemTextJsonContentSerializer WithContext(System.Text.Json.Serialization.JsonSerializerContext context) { } - public Refit.SystemTextJsonContentSerializer WithContext(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - public static Refit.SystemTextJsonContentSerializer ForContext(System.Text.Json.Serialization.JsonSerializerContext context) { } - public static Refit.SystemTextJsonContentSerializer ForContext(System.Text.Json.Serialization.JsonSerializerContext context, bool allowReflectionFallback) { } - public static System.Text.Json.JsonSerializerOptions GetDefaultJsonSerializerOptions() { } - public static System.Text.Json.JsonSerializerOptions GetFastPathJsonSerializerOptions() { } -} -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class SystemTextJsonQueryConverter : Refit.IQueryConverter -{ - public SystemTextJsonQueryConverter() { } - public void Flatten(T value, string keyPrefix, ref Refit.GeneratedQueryStringBuilder builder, Refit.RefitSettings settings) { } -} -[System.AttributeUsage(System.AttributeTargets.Method)] -[System.Diagnostics.DebuggerDisplay("{Milliseconds}")] -public sealed class TimeoutAttribute : System.Attribute -{ - public TimeoutAttribute(int milliseconds) { } - public int Milliseconds { get; } -} -public static class UniqueName -{ - public static string ForType(System.Type refitInterfaceType) { } - public static string ForType(System.Type refitInterfaceType, object? serviceKey) { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string ForType() { } - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - public static string ForType(object? serviceKey) { } -} -[System.AttributeUsage(System.AttributeTargets.Parameter)] -[System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] -public sealed class UrlAttribute : System.Attribute -{ - public UrlAttribute() { } - public bool AllowRelative { get; set; } -} -public enum UrlResolutionMode -{ - RefitLegacy = 0, - Rfc3986 = 1, -} -[System.Diagnostics.DebuggerDisplay("ValidationApiException: {StatusCode}, Content = {Content}")] -public class ValidationApiException : Refit.ApiException -{ - public ValidationApiException(string message) { } - public ValidationApiException(string message, System.Exception innerException) { } - public Refit.ProblemDetails? Content { get; } - public static Refit.ValidationApiException Create(Refit.ApiException exception) { } -} diff --git a/src/Refit/ReflectionHooks.cs b/src/Refit/ReflectionHooks.cs new file mode 100644 index 000000000..48643356d --- /dev/null +++ b/src/Refit/ReflectionHooks.cs @@ -0,0 +1,94 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Runtime.CompilerServices; +using System.Text.Json.Serialization.Metadata; + +namespace Refit; + +/// Holds the run-time implementations the Refit.Reflection package registers for work core Refit cannot do without reflection. +internal static class ReflectionHooks +{ + /// Gets or sets the flattener for complex form values, or when Refit.Reflection is not loaded. + internal static IFormObjectFlattener? FormObjectFlattener { get; set; } + + /// Gets or sets the reader of [EnumMember] values for run-time-typed enums, or when Refit.Reflection is not loaded. + internal static Func? EnumMemberValueResolver { get; set; } + + /// Gets or sets the factory for System.Text.Json's reflection resolver, or when Refit.Reflection is not loaded. + internal static Func? DefaultJsonResolverFactory { get; set; } + + /// Gets or sets the test for a reflection-based resolver, or when Refit.Reflection is not loaded. + internal static Func? ReflectionResolverTest { get; set; } + + /// Gets or sets the copier of reflection resolver modifiers onto another resolver, or when Refit.Reflection is not loaded. + internal static Func, IJsonTypeInfoResolver>? ModifierCarrier { get; set; } + + /// Determines whether a resolver is the reflection-based one. + /// The resolver to test. + /// when Refit.Reflection is loaded and the resolver is reflection based. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool IsReflectionResolver(IJsonTypeInfoResolver resolver) => IsReflectionResolver(ReflectionResolverTest, resolver); + + /// Determines whether a resolver is the reflection-based one using a given test. + /// The registered test, or when none is registered. + /// The resolver to test. + /// when a test is registered and accepts the resolver. + internal static bool IsReflectionResolver(Func? test, IJsonTypeInfoResolver resolver) => + test is not null && test(resolver); + + /// Applies the modifiers of reflection resolvers to another resolver. + /// The resolver that receives the modifiers. + /// The reflection resolvers whose modifiers are carried over. + /// The resolver with every modifier applied, or the same resolver when none are carried. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static IJsonTypeInfoResolver CarryModifiers(IJsonTypeInfoResolver resolver, List reflective) => + CarryModifiers(ModifierCarrier, resolver, reflective); + + /// Applies the modifiers of reflection resolvers to another resolver using a given carrier. + /// The registered carrier, or when none is registered. + /// The resolver that receives the modifiers. + /// The reflection resolvers whose modifiers are carried over. + /// The resolver with every modifier applied, or the same resolver when none are carried. + internal static IJsonTypeInfoResolver CarryModifiers( + Func, IJsonTypeInfoResolver>? carrier, + IJsonTypeInfoResolver resolver, + List reflective) => + carrier is null ? resolver : carrier(resolver, reflective); + + /// Creates System.Text.Json's reflection resolver or explains how to avoid needing one. + /// A new reflection resolver. + /// The Refit.Reflection package is not loaded. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static IJsonTypeInfoResolver CreateDefaultJsonResolver() => CreateDefaultJsonResolver(DefaultJsonResolverFactory); + + /// Creates System.Text.Json's reflection resolver from a factory or explains how to avoid needing one. + /// The registered factory, or when none is registered. + /// A new reflection resolver. + /// is . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static IJsonTypeInfoResolver CreateDefaultJsonResolver(Func? factory) => + (factory + ?? throw new NotSupportedException( + "These JSON serializer options have no type metadata. Supply a source-generated JsonSerializerContext " + + "(for example RefitSettings.ForJsonContext), or reference the Refit.Reflection package and call " + + "ReflectionSupport.EnsureRegistered() to use reflection-based JSON."))(); + + /// Gets the registered form flattener or explains how to add one. + /// The registered flattener. + /// The Refit.Reflection package is not loaded. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static IFormObjectFlattener RequireFormObjectFlattener() => Require(FormObjectFlattener); + + /// Returns the flattener or explains how to add one. + /// The flattener to check, or when none is registered. + /// The same flattener. + /// is . + internal static IFormObjectFlattener Require(IFormObjectFlattener? flattener) => + flattener + ?? throw new NotSupportedException( + "Flattening a nested or run-time-typed form value needs the reflection support in the Refit.Reflection " + + "package. Add a reference to it and call ReflectionSupport.EnsureRegistered(), or use a form body made " + + "only of simple values and collections so the source generator can handle it."); +} diff --git a/src/Refit/ReflectionRequestBuilderResolver.cs b/src/Refit/ReflectionRequestBuilderResolver.cs deleted file mode 100644 index 28e9a760a..000000000 --- a/src/Refit/ReflectionRequestBuilderResolver.cs +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. -// ReactiveUI and Contributors licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -using System.Diagnostics.CodeAnalysis; - -namespace Refit; - -/// -/// Lazily resolves the reflection request-builder factory from the optional Refit.Reflection package. Core Refit -/// never references that assembly statically, so applications that only use generated clients neither ship it nor -/// carry the reflection pipeline through trimming and Native AOT. -/// -internal static class ReflectionRequestBuilderResolver -{ - /// The assembly-qualified name of the reflection request-builder factory. - private const string FactoryTypeName = "Refit.RequestBuilderFactory, Refit.Reflection"; - - /// The lazily resolved factory instance. - private static IRequestBuilderFactory? _factory; - - /// Gets the reflection request-builder factory, loading the Refit.Reflection assembly on first use. - /// The factory instance. - /// The Refit.Reflection package is not installed. - [RequiresUnreferencedCode("The reflection request builder requires runtime type lookup and request metadata.")] - internal static IRequestBuilderFactory GetFactory() => _factory ??= CreateFactory(); - - /// Loads and instantiates the reflection request-builder factory. - /// The factory instance. - /// The Refit.Reflection assembly is not present, so the factory type cannot be loaded. - [RequiresUnreferencedCode("The reflection request builder requires runtime type lookup and request metadata.")] - [ExcludeFromCodeCoverage] // The not-installed throw is unreachable in-process: Refit.Reflection is always present when this resolver runs. - internal static IRequestBuilderFactory CreateFactory() => - Type.GetType(FactoryTypeName, throwOnError: false) is { } factoryType - && Activator.CreateInstance(factoryType) is IRequestBuilderFactory factory - ? factory - : throw new NotSupportedException( - "This interface needs the reflection request builder, which is not installed. Add a reference to " - + "the Refit.Reflection NuGet package to opt in to it, or change the interface so every method " - + "generates inline (the RF006 diagnostic reports the methods that cannot) and use a generated " - + "client via RestService.ForGenerated or AddRefitGeneratedClient."); -} diff --git a/src/Refit/RequestBuilder.cs b/src/Refit/RequestBuilder.cs deleted file mode 100644 index 5d6debc18..000000000 --- a/src/Refit/RequestBuilder.cs +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. -// ReactiveUI and Contributors licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; - -namespace Refit; - -/// -/// Provides static methods for creating request builders for Refit interface types. This class enables the -/// generation of strongly-typed HTTP client implementations based on interface definitions and optional settings. -/// -/// Request builders generated by this class use reflection to analyze the provided interface -/// type and create implementations for HTTP API calls. When using trimming or linking, ensure that referenced -/// interfaces and data transfer objects are preserved, as reflection is required for correct operation. All members -/// of this class are thread-safe and can be used concurrently across multiple threads. -public static class RequestBuilder -{ - /// Creates an HTTP request builder for the specified interface type. - /// The interface type that defines the HTTP API methods to be implemented by the request builder. Must be an - /// interface. - /// The Refit settings to use for configuring the request builder. May be null to use default settings. - /// An instance of IRequestBuilder T that can be used to construct HTTP requests for the specified interface - /// type. - /// Use this method to obtain a request builder for a given API interface, typically for - /// advanced scenarios such as custom client generation or integration with dependency injection. The returned - /// builder can be used to create HTTP requests corresponding to the methods defined on the interface. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - public static IRequestBuilder ForType< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(RefitSettings? settings) => - ReflectionRequestBuilderResolver.GetFactory().Create(settings); - - /// Creates a request builder for the specified type, enabling construction of requests against its members. - /// The type for which to create the request builder. This type's methods will be available for request - /// construction. - /// An object that can be used to build requests for the specified type. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - public static IRequestBuilder ForType< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>() => - ReflectionRequestBuilderResolver.GetFactory().Create(null); - - /// Creates an implementation of the specified Refit interface for making HTTP requests. - /// The interface type that defines the HTTP API contract. Must be an interface, including a closed generic interface, decorated with Refit - /// attributes. - /// Optional settings to customize the behavior of the generated request builder. If null, default settings are - /// used. - /// An IRequestBuilder instance that can be used to construct HTTP requests for the specified interface. - /// The returned IRequestBuilder uses reflection to analyze the provided interface type. - /// When using trimming or linking, ensure that all referenced interfaces and data transfer objects are - /// preserved to avoid runtime errors. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - public static IRequestBuilder ForType( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - RefitSettings? settings) => - ReflectionRequestBuilderResolver.GetFactory().Create(refitInterfaceType, settings); - - /// Creates an instance of an IRequestBuilder for the specified Refit interface type. - /// The interface type that defines the Refit API contract. Must be an interface, including a closed generic interface, decorated with Refit - /// attributes. - /// An IRequestBuilder instance that can be used to construct HTTP requests for the specified interface type. - /// The specified interface type must be decorated with Refit attributes to define the - /// API endpoints. If trimming is enabled, ensure that all referenced interfaces and data transfer objects are - /// preserved, as reflection is used to analyze the interface methods. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [RequiresUnreferencedCode("Building requests from reflected interface methods requires interface and request object metadata to be available at runtime.")] - public static IRequestBuilder ForType( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType) => - ForType(refitInterfaceType, null); -} diff --git a/src/Refit/RequestExecutionHelpers.cs b/src/Refit/RequestExecutionHelpers.cs index e9e6322fc..855407197 100644 --- a/src/Refit/RequestExecutionHelpers.cs +++ b/src/Refit/RequestExecutionHelpers.cs @@ -278,6 +278,7 @@ internal static async Task CaptureRequestContentAsync( /// Returns the response content, substituting empty content when the response has none. /// The response whose content is read. /// The response content, or empty content when none is present. + [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] // Content is non-null in the BCL on every supported runtime, so the fallback branch is unreachable. internal static HttpContent EnsureResponseContent(HttpResponseMessage response) { var content = response.Content ?? new StringContent(string.Empty); diff --git a/src/Refit/RestService.cs b/src/Refit/RestService.cs index a74d199f8..d1016753c 100644 --- a/src/Refit/RestService.cs +++ b/src/Refit/RestService.cs @@ -15,20 +15,17 @@ public static partial class RestService public static class RestService #endif { - /// Caches the resolved generated implementation type per interface. - private static readonly ConcurrentDictionary _typeMapping = new(); - /// Holds registered source-generated implementation factories per interface. - private static readonly ConcurrentDictionary> _generatedFactories = + internal static readonly ConcurrentDictionary> _generatedFactories = new(); + /// Caches the module-initializer runner so resolving a client allocates no delegate. + internal static readonly Action _generatedRegistrationRunner = RunGeneratedRegistrations; + /// Holds source-generated factories that only need settings and avoid request-builder reflection. private static readonly ConcurrentDictionary> _generatedSettingsFactories = new(); - /// Caches the module-initializer runner so resolving a client allocates no delegate. - private static readonly Action _generatedRegistrationRunner = RunGeneratedRegistrations; - /// Registers a source-generated Refit implementation factory. /// The Refit interface type. /// The generated implementation factory. @@ -98,18 +95,12 @@ public static T ForGenerated(HttpClient client, RefitSettings settings) ArgumentExceptionHelper.ThrowIfNull(client); ArgumentExceptionHelper.ThrowIfNull(settings); -#if NET5_0_OR_GREATER if (TryResolveGeneratedClient(client, settings, _generatedRegistrationRunner, out var instance)) { return instance; } throw CreateMissingGeneratedFactoryException(typeof(T)); -#else - return TryResolveGeneratedClient(client, settings, _generatedRegistrationRunner, out var instance) - ? instance - : (T)CreateByGeneratedTypeName(typeof(T), client, settings); -#endif } /// Create a source-generated Refit implementation without falling back to reflection. @@ -160,18 +151,12 @@ public static object ForGenerated( ArgumentExceptionHelper.ThrowIfNull(client); ArgumentExceptionHelper.ThrowIfNull(settings); -#if NET5_0_OR_GREATER if (TryResolveGeneratedClient(refitInterfaceType, client, settings, _generatedRegistrationRunner, out var instance)) { return instance; } throw CreateMissingGeneratedFactoryException(refitInterfaceType); -#else - return TryResolveGeneratedClient(refitInterfaceType, client, settings, _generatedRegistrationRunner, out var instance) - ? instance - : CreateByGeneratedTypeName(refitInterfaceType, client, settings); -#endif } /// Create a source-generated Refit implementation without falling back to reflection. @@ -191,208 +176,6 @@ public static object ForGenerated( return ForGenerated(refitInterfaceType, client, settings); } - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// The the implementation will use to send requests. - /// to use to build requests. - /// An instance that implements . - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and constructor metadata.")] - public static T For< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(HttpClient client, IRequestBuilder builder) => (T)For(typeof(T), client, builder); - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// The the implementation will use to send requests. - /// to use to configure the HttpClient. - /// An instance that implements . - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(HttpClient client, RefitSettings? settings) - { - var resolvedSettings = settings ?? new(); - - // A generated settings factory means every method builds its request inline, so the reflection - // request builder (and the Refit.Reflection assembly) is never needed for this interface. - if (TryResolveInlineClient(client, resolvedSettings, _generatedRegistrationRunner, out var instance)) - { - return instance; - } - - var requestBuilder = RequestBuilder.ForType(settings); - - return For(client, requestBuilder); - } - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// The the implementation will use to send requests. - /// An instance that implements . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(HttpClient client) => For(client, (RefitSettings?)null); - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// Base address the implementation will use. - /// to use to configure the HttpClient. - /// An instance that implements . - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(string hostUrl, RefitSettings? settings) - { - var client = CreateHttpClient(hostUrl, settings); - - return For(client, settings); - } - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// Base address the implementation will use. - /// An instance that implements . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static T For< - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - T>(string hostUrl) => For(hostUrl, null); - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// The the implementation will use to send requests. - /// to use to build requests. - /// An instance that implements . - [RequiresUnreferencedCode("Creating a generated client by Type requires runtime type lookup and constructor metadata.")] - public static object For( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - HttpClient client, - IRequestBuilder builder) - { - if (_generatedFactories.TryGetValue(refitInterfaceType, out var factory)) - { - return factory(client, builder); - } - - var generatedType = _typeMapping.GetOrAdd(refitInterfaceType, GetGeneratedType); - - return Activator.CreateInstance(generatedType, client, builder)!; - } - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// The the implementation will use to send requests. - /// to use to configure the HttpClient. - /// An instance that implements . - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - HttpClient client, - RefitSettings? settings) - { - var resolvedSettings = settings ?? new(); - - // A generated settings factory means every method builds its request inline, so the reflection - // request builder (and the Refit.Reflection assembly) is never needed for this interface. - if (TryResolveInlineClient(refitInterfaceType, client, resolvedSettings, _generatedRegistrationRunner, out var instance)) - { - return instance; - } - - var requestBuilder = RequestBuilder.ForType(refitInterfaceType, settings); - - return For(refitInterfaceType, client, requestBuilder); - } - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// The the implementation will use to send requests. - /// An instance that implements . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - HttpClient client) => For(refitInterfaceType, client, (RefitSettings?)null); - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// Base address the implementation will use. - /// to use to configure the HttpClient. - /// An instance that implements . - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - string hostUrl, - RefitSettings? settings) - { - var client = CreateHttpClient(hostUrl, settings); - - return For(refitInterfaceType, client, settings); - } - - /// Generate a Refit implementation of the specified interface. - /// Interface to create the implementation for. - /// Base address the implementation will use. - /// An instance that implements . - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [RequiresUnreferencedCode("Creating a generated client through the reflection path requires runtime type lookup and request metadata.")] - public static object For( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType, - string hostUrl) => For(refitInterfaceType, hostUrl, null); - /// Create an with as the base address. /// Base address. /// to use to configure the HttpClient. @@ -538,24 +321,6 @@ internal static bool TryResolveInlineClient( return TryCreateInlineClient(refitInterfaceType, client, settings, out instance); } - /// Resolves the generated implementation type for a Refit interface. - /// The Refit interface type. - /// The generated implementation type. - [return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors)] - [RequiresUnreferencedCode("Resolving a generated client type by name requires runtime type lookup.")] - internal static Type GetGeneratedType( - [DynamicallyAccessedMembers( - DynamicallyAccessedMemberTypes.Interfaces - | DynamicallyAccessedMemberTypes.PublicMethods - | DynamicallyAccessedMemberTypes.NonPublicMethods)] - Type refitInterfaceType) - { - var typeName = UniqueName.ForType(refitInterfaceType); - - return Type.GetType(typeName, false) - ?? throw CreateMissingGeneratedFactoryException(refitInterfaceType); - } - /// Creates the exception thrown when no source-generated implementation is available. /// The Refit interface type. /// The generated-client exception. @@ -672,25 +437,6 @@ private static bool TryCreateInlineClient( return false; } -#if !NET5_0_OR_GREATER - /// Creates a generated implementation by resolving its emitted type name. - /// The Refit interface type. - /// The the implementation will use to send requests. - /// to use to configure the generated client. - /// An instance that implements . - /// - /// .NET Framework has no [ModuleInitializer], so the generator emits no registrations for those targets and - /// the factory registries stay empty there. Resolving the generated type by name is the same fallback the - /// reflection path already uses, and it keeps the modern targets free of runtime type lookup. - /// - private static object CreateByGeneratedTypeName(Type refitInterfaceType, HttpClient client, RefitSettings settings) - { - var generatedType = _typeMapping.GetOrAdd(refitInterfaceType, GetGeneratedType); - - return Activator.CreateInstance(generatedType, client, new GeneratedOnlyRequestBuilder(settings))!; - } -#endif - /// Holds the typed generated factory for a single Refit interface. /// The Refit interface type. internal static class GeneratedFactory diff --git a/src/Refit/SystemTextJsonContentSerializer.JsonContext.cs b/src/Refit/SystemTextJsonContentSerializer.JsonContext.cs index 4d959aedf..8271b3e21 100644 --- a/src/Refit/SystemTextJsonContentSerializer.JsonContext.cs +++ b/src/Refit/SystemTextJsonContentSerializer.JsonContext.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. #if NET8_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; using System.Net.Http.Json; using System.Text.Json; using System.Text.Json.Serialization; @@ -176,7 +175,7 @@ internal static bool IsRegistered( foreach (var resolver in options.TypeInfoResolverChain) { hasContext |= ReferenceEquals(resolver, context); - hasReflection |= resolver is DefaultJsonTypeInfoResolver; + hasReflection |= ReflectionHooks.IsReflectionResolver(resolver); } return hasContext && hasReflection == allowReflectionFallback; @@ -187,8 +186,6 @@ internal static bool IsRegistered( /// The context to register. /// Whether reflection may describe the types no other resolver describes. /// New options that keep everything in and resolve . - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] internal static JsonSerializerOptions ComposeOptions( JsonSerializerOptions source, JsonSerializerContext context, @@ -198,18 +195,18 @@ internal static JsonSerializerOptions ComposeOptions( var chain = options.TypeInfoResolverChain; List leading = []; - List reflective = []; + List reflective = []; SplitResolvers(chain, context, leading, reflective); IJsonTypeInfoResolver contextResolver = context; if (!allowReflectionFallback) { - contextResolver = CarryModifiers(context, reflective); + contextResolver = ReflectionHooks.CarryModifiers(context, reflective); reflective.Clear(); } else if (reflective.Count == 0) { - reflective.Add(new()); + reflective.Add(ReflectionHooks.CreateDefaultJsonResolver()); } chain.Clear(); @@ -229,7 +226,7 @@ internal static void SplitResolvers( IList chain, JsonSerializerContext context, List leading, - List reflective) + List reflective) { foreach (var resolver in chain) { @@ -238,9 +235,9 @@ internal static void SplitResolvers( continue; } - if (resolver is DefaultJsonTypeInfoResolver reflectionResolver) + if (ReflectionHooks.IsReflectionResolver(resolver)) { - reflective.Add(reflectionResolver); + reflective.Add(resolver); } else { @@ -249,25 +246,6 @@ internal static void SplitResolvers( } } - /// Applies the contract modifiers of reflection resolvers to another resolver, so registrations such as polymorphism survive. - /// The resolver that receives the modifiers. - /// The reflection resolvers whose modifiers are carried over. - /// The resolver with every modifier applied. - internal static IJsonTypeInfoResolver CarryModifiers( - IJsonTypeInfoResolver resolver, - List reflective) - { - foreach (var reflectionResolver in reflective) - { - foreach (var modifier in reflectionResolver.Modifiers) - { - resolver = resolver.WithAddedModifier(modifier); - } - } - - return resolver; - } - /// Appends every resolver to a chain. /// The resolver type. /// The chain to extend. diff --git a/src/Refit/SystemTextJsonContentSerializer.cs b/src/Refit/SystemTextJsonContentSerializer.cs index fc9aa53f2..608e21e5d 100644 --- a/src/Refit/SystemTextJsonContentSerializer.cs +++ b/src/Refit/SystemTextJsonContentSerializer.cs @@ -8,13 +8,10 @@ using System.Diagnostics.CodeAnalysis; using System.Net.Http.Json; using System.Net.ServerSentEvents; -using System.Reflection; using System.Runtime.CompilerServices; using System.Text.Json; using System.Text.Json.Serialization; -#if NET8_0_OR_GREATER using System.Text.Json.Serialization.Metadata; -#endif namespace Refit; @@ -29,11 +26,10 @@ public sealed partial class SystemTextJsonContentSerializer(JsonSerializerOption #else public sealed class SystemTextJsonContentSerializer(JsonSerializerOptions jsonSerializerOptions) #endif - : IHttpContentSerializer, IStreamingContentSerializer, ISynchronousContentSerializer, ISynchronousContentDeserializer + : IHttpContentSerializer, IStreamingContentSerializer, ISynchronousContentSerializer, ISynchronousContentDeserializer, IContentSerializerNameStyle { - /// Justification shared by the reflection-fallback trim/AOT suppressions. - private const string ReflectionFallbackJustification = - "Serializing or deserializing without supplied JSON type metadata requires runtime serializer metadata."; + /// Guards the one-time assignment of the default resolver. + private readonly object _resolverLock = new(); /// Initializes a new instance of the class. public SystemTextJsonContentSerializer() @@ -45,8 +41,33 @@ public SystemTextJsonContentSerializer() /// registered type's without reflection. public JsonSerializerOptions SerializerOptions => jsonSerializerOptions; + /// + public ContentSerializerNameStyle NameStyle => ContentSerializerNameStyle.SystemTextJson; + + /// + /// Gets the options with type metadata available. Options that carry no + /// get the reflection resolver the Refit.Reflection package registers, or fail with a message that explains how to + /// supply a source-generated context or register that package. + /// + private JsonSerializerOptions ReadyOptions + { + get + { + if (jsonSerializerOptions.TypeInfoResolver is null && !jsonSerializerOptions.IsReadOnly) + { + AssignDefaultResolver(); + } + + return jsonSerializerOptions; + } + } + /// Creates new and fills it with default parameters. /// The default . + [SuppressMessage( + "Design", + "CA1024:Use properties where appropriate", + Justification = "Returns a new mutable options instance on each call; a property would wrongly imply a cached value.")] [SuppressMessage( "Performance", "PSH1416:Cache constructed objects in a static readonly field", @@ -58,22 +79,18 @@ public static JsonSerializerOptions GetDefaultJsonSerializerOptions() { PropertyNameCaseInsensitive = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, - NumberHandling = JsonNumberHandling.AllowReadingFromString, #if NET10_0_OR_GREATER AllowDuplicateProperties = false, #endif }; - jsonSerializerOptions.Converters.Add(new ObjectToInferredTypesConverter()); - jsonSerializerOptions.Converters.Add(new CamelCaseStringEnumConverter()); return jsonSerializerOptions; } /// /// Creates that are eligible for the System.Text.Json source-generated - /// fast-path on serialization. Unlike , these options add no - /// converters and leave number handling at its default. Custom converters and number handling that changes - /// writing can disable the fast-path; AllowReadingFromString alone does not. Assign a generated TypeInfoResolver (a + /// fast-path on serialization. They are the same as : Refit adds no + /// converters and leaves number handling at its default, because either would disable the fast-path. Assign a generated TypeInfoResolver (a /// generated in or /// mode) to enable it. The fast-path runs through the synchronous /// serialization primitives (SerializeToUtf8Bytes / Serialize(Utf8JsonWriter, ...)); the @@ -101,26 +118,14 @@ public static JsonSerializerOptions GetFastPathJsonSerializerOptions() => /// public HttpContent ToHttpContent(T item) { + var options = ReadyOptions; var serializeByRuntimeType = item is not null && (typeof(T).IsInterface || typeof(T).IsAbstract) -#if NET8_0_OR_GREATER - && !DeclaredTypeIsPolymorphic(typeof(T), jsonSerializerOptions); -#else - && !DeclaredTypeIsPolymorphic(typeof(T)); -#endif + && !DeclaredTypeIsPolymorphic(typeof(T), options); -#if NET8_0_OR_GREATER - return serializeByRuntimeType switch - { - true => ToHttpContentRuntimeTyped(item!, item!.GetType()), - false when jsonSerializerOptions.TypeInfoResolver is not null => JsonContent.Create(item, GetJsonTypeInfo()), - _ => ToHttpContentReflection(item), - }; -#else return serializeByRuntimeType ? ToHttpContentRuntimeTyped(item!, item!.GetType()) - : ToHttpContentReflection(item); -#endif + : JsonContent.Create(item, GetJsonTypeInfo(options)); } /// @@ -170,13 +175,7 @@ public HttpContent ToStreamingHttpContent(T item) public Task FromHttpContentAsync( HttpContent content, CancellationToken cancellationToken = default) => -#if NET8_0_OR_GREATER - jsonSerializerOptions.TypeInfoResolver is not null - ? content.ReadFromJsonAsync(GetJsonTypeInfo(), cancellationToken) - : FromHttpContentReflectionAsync(content, cancellationToken); -#else - FromHttpContentReflectionAsync(content, cancellationToken); -#endif + content.ReadFromJsonAsync(GetJsonTypeInfo(), cancellationToken); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -184,14 +183,8 @@ jsonSerializerOptions.TypeInfoResolver is not null "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Type parameter intentionally specified explicitly by callers.")] -#if NET8_0_OR_GREATER public T? DeserializeFromString(string content) => - jsonSerializerOptions.TypeInfoResolver is not null - ? JsonSerializer.Deserialize(content, GetJsonTypeInfo()) - : DeserializeFromStringReflection(content); -#else - public T? DeserializeFromString(string content) => DeserializeFromStringReflection(content); -#endif + JsonSerializer.Deserialize(content, GetJsonTypeInfo()); /// [SuppressMessage( @@ -213,38 +206,12 @@ jsonSerializerOptions.TypeInfoResolver is not null }; } - /// - /// Calculates what the field name should be for the given property. This may be affected by custom attributes the serializer understands. - /// - /// A PropertyInfo object. - /// - /// The calculated field name. - /// - /// propertyInfo. - public string? GetFieldNameForProperty(PropertyInfo propertyInfo) - { - ArgumentExceptionHelper.ThrowIfNull(propertyInfo); - return propertyInfo.GetCustomAttribute(true)?.Name; - } - -#if NET8_0_OR_GREATER /// Determines whether the declared type is configured for polymorphic serialization. /// The declared type to inspect. /// The serializer options to consult for type metadata. /// if the type is polymorphic; otherwise . internal static bool DeclaredTypeIsPolymorphic(Type type, JsonSerializerOptions jsonSerializerOptions) => - type.IsDefined(typeof(JsonPolymorphicAttribute), false) - || type.IsDefined(typeof(JsonDerivedTypeAttribute), false) - || (jsonSerializerOptions.TypeInfoResolver is not null - && GetJsonTypeInfo(type, jsonSerializerOptions).PolymorphismOptions is not null); -#else - /// Determines whether attributes configure the declared type for polymorphic serialization. - /// The declared type to inspect. - /// if the type is polymorphic; otherwise . - internal static bool DeclaredTypeIsPolymorphic(Type type) => - type.IsDefined(typeof(JsonPolymorphicAttribute), false) - || type.IsDefined(typeof(JsonDerivedTypeAttribute), false); -#endif + GetJsonTypeInfo(type, jsonSerializerOptions).PolymorphismOptions is not null; #if !NET9_0_OR_GREATER /// Determines whether a buffered line is blank, ignoring a trailing carriage return and treating spaces and tabs as blank. @@ -285,11 +252,11 @@ internal static byte[] GrowLineScanBuffer(byte[] buffer, int length, int growthF } #endif -#if NET8_0_OR_GREATER /// Gets the JSON type metadata for the given runtime type from the supplied options. /// The runtime type to resolve metadata for. /// The serializer options to consult. /// The JSON type metadata. + [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static JsonTypeInfo GetJsonTypeInfo(Type type, JsonSerializerOptions jsonSerializerOptions) => jsonSerializerOptions.GetTypeInfo(type); // Returns non-null metadata for the requested type or throws; there is no null case to guard. @@ -297,6 +264,7 @@ internal static JsonTypeInfo GetJsonTypeInfo(Type type, JsonSerializerOptions js /// The type to resolve metadata for. /// The serializer options to consult. /// The JSON type metadata. + [MethodImpl(MethodImplOptions.AggressiveInlining)] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", @@ -306,98 +274,48 @@ internal static JsonTypeInfo GetJsonTypeInfo(JsonSerializerOptions jsonSer jsonSerializerOptions.GetTypeInfo(); #else (JsonTypeInfo)GetJsonTypeInfo(typeof(T), jsonSerializerOptions); -#endif #endif /// Determines whether writes a declared-type value as it writes it passed as . /// The declared type of the values. /// /// when the type has no derived types (a value type or sealed class), so the runtime type - /// the path resolves is always , and no configured converter - /// replaces the built-in handling of . + /// the path resolves is always . /// - internal bool WritesDeclaredTypeAsObject(Type declaredType) - { - if (!declaredType.IsValueType && !declaredType.IsSealed) - { - return false; - } - - foreach (var converter in jsonSerializerOptions.Converters) - { - // ObjectToInferredTypesConverter is the built-in handling of object the doc above refers to: its - // Write serializes by the value's own runtime type (see its implementation), which is always - // declaredType here (a value type or sealed class has no derived types), so it writes the same JSON a - // typed write would. Only a converter replacing that behavior forces the untyped fallback. - if (converter is not ObjectToInferredTypesConverter && converter.CanConvert(typeof(object))) - { - return false; - } - } - - return true; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool WritesDeclaredTypeAsObject(Type declaredType) => + declaredType.IsValueType || declaredType.IsSealed; -#if NET8_0_OR_GREATER /// Gets the JSON type metadata for the given type from the configured options. /// The type to resolve metadata for. /// The JSON type metadata. + [MethodImpl(MethodImplOptions.AggressiveInlining)] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Type parameter intentionally specified explicitly by callers.")] - internal JsonTypeInfo GetJsonTypeInfo() => GetJsonTypeInfo(jsonSerializerOptions); -#endif + internal JsonTypeInfo GetJsonTypeInfo() => GetJsonTypeInfo(ReadyOptions); - /// Serializes the item to HTTP content using the supplied runtime type. - /// The item to serialize. - /// The runtime type to serialize the item as. - /// The serialized HTTP content. -#if NET8_0_OR_GREATER - internal JsonContent ToHttpContentRuntimeTyped(object item, Type runtimeType) => - jsonSerializerOptions.TypeInfoResolver is not null - ? JsonContent.Create(item, GetJsonTypeInfo(runtimeType, jsonSerializerOptions)) - : ToHttpContentRuntimeReflection(item, runtimeType); -#else - internal JsonContent ToHttpContentRuntimeTyped(object item, Type runtimeType) => ToHttpContentRuntimeReflection(item, runtimeType); -#endif + /// Assigns the reflection resolver once, even when several threads share this serializer. A thread that loses the race + /// must not set it again, because the winner's first use makes the options read-only. + internal void AssignDefaultResolver() + { + lock (_resolverLock) + { + // The winner's resolver is already set, so the options may be read-only by now and must not be touched. + jsonSerializerOptions.TypeInfoResolver ??= ReflectionHooks.CreateDefaultJsonResolver(); + } + } - /// Serializes the item by runtime type using reflection-based metadata (used when the options provide no resolver). + /// Serializes the item to HTTP content using the supplied runtime type. /// The item to serialize. /// The runtime type to serialize the item as. /// The serialized HTTP content. [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - internal JsonContent ToHttpContentRuntimeReflection(object item, Type runtimeType) => - JsonContent.Create(item, runtimeType, options: jsonSerializerOptions); - - /// Serializes the item using reflection-based metadata (used when the options provide no resolver). - /// The type of the item being serialized. - /// The item to serialize. - /// The serialized HTTP content. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - internal JsonContent ToHttpContentReflection(T item) => - JsonContent.Create(item, options: jsonSerializerOptions); - - /// Deserializes the content using reflection-based metadata (used when the options provide no resolver). - /// The type to deserialize. - /// The HTTP content to read from. - /// A token used to cancel the operation. - /// The deserialized value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - internal Task FromHttpContentReflectionAsync(HttpContent content, CancellationToken cancellationToken) => - content.ReadFromJsonAsync(jsonSerializerOptions, cancellationToken); + internal JsonContent ToHttpContentRuntimeTyped(object item, Type runtimeType) => + JsonContent.Create(item, GetJsonTypeInfo(runtimeType, ReadyOptions)); - /// Serializes an item to UTF-8 JSON bytes, using source-gen metadata when a resolver is configured. + /// Serializes an item to UTF-8 JSON bytes through the configured type metadata. /// The type of the item being serialized. /// The item to serialize. /// The UTF-8 encoded JSON. @@ -406,88 +324,33 @@ internal JsonContent ToHttpContentReflection(T item) => "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Type parameter intentionally specified explicitly by callers.")] -#if NET8_0_OR_GREATER internal byte[] SerializeToUtf8Bytes(T item) => - jsonSerializerOptions.TypeInfoResolver is not null - ? JsonSerializer.SerializeToUtf8Bytes(item, GetJsonTypeInfo()) - : SerializeToUtf8BytesReflection(item); -#else - internal byte[] SerializeToUtf8Bytes(T item) => SerializeToUtf8BytesReflection(item); -#endif + JsonSerializer.SerializeToUtf8Bytes(item, GetJsonTypeInfo()); - /// Serializes an item to UTF-8 JSON bytes using reflection-based metadata. - /// The type of the item being serialized. - /// The item to serialize. - /// The UTF-8 encoded JSON. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - internal byte[] SerializeToUtf8BytesReflection(T item) => - JsonSerializer.SerializeToUtf8Bytes(item, jsonSerializerOptions); - - /// Writes an item to a , using source-gen metadata when a resolver is configured. - /// The type of the item being serialized. - /// The item to serialize. - /// The writer to serialize into. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] -#if NET8_0_OR_GREATER - internal void SerializeToWriter(T item, Utf8JsonWriter writer) - { - if (jsonSerializerOptions.TypeInfoResolver is not null) - { - JsonSerializer.Serialize(writer, item, GetJsonTypeInfo()); - } - else - { - SerializeToWriterReflection(item, writer); - } - } -#else - internal void SerializeToWriter(T item, Utf8JsonWriter writer) => SerializeToWriterReflection(item, writer); -#endif - - /// Writes an item to a using reflection-based metadata. + /// Writes an item to a through the configured type metadata. /// The type of the item being serialized. /// The item to serialize. /// The writer to serialize into. [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Type parameter intentionally specified explicitly by callers.")] - internal void SerializeToWriterReflection(T item, Utf8JsonWriter writer) => - JsonSerializer.Serialize(writer, item, jsonSerializerOptions); + internal void SerializeToWriter(T item, Utf8JsonWriter writer) => + JsonSerializer.Serialize(writer, item, GetJsonTypeInfo()); /// Streams the elements of a single top-level JSON array. /// The element type to deserialize. /// The response body stream. /// A token to cancel enumeration. /// An asynchronous sequence of deserialized elements. + [MethodImpl(MethodImplOptions.AggressiveInlining)] [SuppressMessage( "Design", "SST2307:Generic method type parameters should be inferable from the parameters", Justification = "Type parameter intentionally specified explicitly by callers.")] - internal IAsyncEnumerable DeserializeJsonArrayAsync(Stream stream, CancellationToken cancellationToken) - { - var options = jsonSerializerOptions; -#if NET8_0_OR_GREATER - return options.TypeInfoResolver is not null - ? JsonSerializer.DeserializeAsyncEnumerable(stream, GetJsonTypeInfo(options), cancellationToken) - : SystemTextJsonStreamingDeserializer.DeserializeJsonArrayReflectionAsync(stream, options, cancellationToken); -#else - return SystemTextJsonStreamingDeserializer.DeserializeJsonArrayReflectionAsync(stream, options, cancellationToken); -#endif - } + internal IAsyncEnumerable DeserializeJsonArrayAsync(Stream stream, CancellationToken cancellationToken) => + JsonSerializer.DeserializeAsyncEnumerable(stream, GetJsonTypeInfo(), cancellationToken); /// Streams newline-delimited JSON values from the response body. /// The element type to deserialize. @@ -500,15 +363,12 @@ internal void SerializeToWriterReflection(T item, Utf8JsonWriter writer) => Justification = "Type parameter intentionally specified explicitly by callers.")] internal IAsyncEnumerable DeserializeJsonLinesAsync(Stream stream, CancellationToken cancellationToken) { - var options = jsonSerializerOptions; #if NET9_0_OR_GREATER // .NET 9 added the topLevelValues overload, which reads a stream of whitespace-separated // top-level JSON values - exactly the JSON Lines framing - without per-line buffering. - return options.TypeInfoResolver is not null - ? JsonSerializer.DeserializeAsyncEnumerable(stream, GetJsonTypeInfo(options), topLevelValues: true, cancellationToken) - : SystemTextJsonStreamingDeserializer.DeserializeJsonLinesTopLevelReflectionAsync(stream, options, cancellationToken); + return JsonSerializer.DeserializeAsyncEnumerable(stream, GetJsonTypeInfo(), topLevelValues: true, cancellationToken); #else - return SystemTextJsonStreamingDeserializer.DeserializeJsonLinesManualAsync(stream, options, cancellationToken); + return SystemTextJsonStreamingDeserializer.DeserializeJsonLinesManualAsync(stream, ReadyOptions, cancellationToken); #endif } @@ -526,7 +386,7 @@ internal void SerializeToWriterReflection(T item, Utf8JsonWriter writer) => Stream stream, [EnumeratorCancellation] CancellationToken cancellationToken) { - var options = jsonSerializerOptions; + var options = ReadyOptions; var parser = SseParser.Create( stream, (eventType, data) => SystemTextJsonStreamingDeserializer.DeserializeSseData(eventType, data, options)); @@ -535,18 +395,4 @@ internal void SerializeToWriterReflection(T item, Utf8JsonWriter writer) => yield return item.Data; } } - - /// Deserializes a buffered string using reflection-based metadata. - /// The type to deserialize. - /// The buffered content string. - /// The deserialized value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - internal T? DeserializeFromStringReflection(string content) => - JsonSerializer.Deserialize(content, jsonSerializerOptions); } diff --git a/src/Refit/SystemTextJsonQueryFlattener.cs b/src/Refit/SystemTextJsonQueryFlattener.cs index 270729e29..267430de9 100644 --- a/src/Refit/SystemTextJsonQueryFlattener.cs +++ b/src/Refit/SystemTextJsonQueryFlattener.cs @@ -105,5 +105,5 @@ internal static void AppendValue( /// The formatted value. [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static string? Format(object value, RefitSettings settings) => - settings.UrlParameterFormatter.Format(value, value.GetType(), value.GetType()); + settings.UrlParameterFormatter.Format(value, GeneratedParameterAttributeProvider.Empty, value.GetType()); } diff --git a/src/Refit/SystemTextJsonStreamingDeserializer.cs b/src/Refit/SystemTextJsonStreamingDeserializer.cs index 65af8741c..e8935ba7f 100644 --- a/src/Refit/SystemTextJsonStreamingDeserializer.cs +++ b/src/Refit/SystemTextJsonStreamingDeserializer.cs @@ -14,52 +14,11 @@ namespace Refit; /// Provides stateless streaming JSON deserialization helpers. internal static class SystemTextJsonStreamingDeserializer { - /// Justification shared by reflection-fallback trim and AOT suppressions. - private const string ReflectionFallbackJustification = - "Deserializing without supplied JSON type metadata requires runtime serializer metadata."; - - /// Streams JSON array elements using reflection-based metadata. - /// The element type to deserialize. - /// The response body stream. - /// The serializer options to use. - /// A token to cancel enumeration. - /// An asynchronous sequence of deserialized elements. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - internal static IAsyncEnumerable DeserializeJsonArrayReflectionAsync( - Stream stream, - JsonSerializerOptions options, - CancellationToken cancellationToken) => - JsonSerializer.DeserializeAsyncEnumerable(stream, options, cancellationToken); - -#if NET9_0_OR_GREATER - /// Streams top-level JSON values using reflection-based metadata. - /// The element type to deserialize. - /// The response body stream. - /// The serializer options to use. - /// A token to cancel enumeration. - /// An asynchronous sequence of deserialized values. - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - internal static IAsyncEnumerable DeserializeJsonLinesTopLevelReflectionAsync( - Stream stream, - JsonSerializerOptions options, - CancellationToken cancellationToken) => - JsonSerializer.DeserializeAsyncEnumerable(stream, topLevelValues: true, options, cancellationToken); -#else +#if !NET9_0_OR_GREATER /// Reads newline-delimited JSON from a stream using a pooled UTF-8 buffer. /// The element type to deserialize. /// The response body stream. - /// The serializer options to use. + /// The serializer options to use. They must carry type metadata. /// A token to cancel enumeration. /// An asynchronous sequence of deserialized values. [SuppressMessage( @@ -138,7 +97,7 @@ internal static class SystemTextJsonStreamingDeserializer /// The buffer holding the line bytes. /// The offset of the line. /// The length of the line. - /// The serializer options to use. + /// The serializer options to use. They must carry type metadata. /// The deserialized value. [SuppressMessage( "Design", @@ -152,35 +111,15 @@ internal static class SystemTextJsonStreamingDeserializer span = span.Slice(0, span.Length - 1); } -#if NET8_0_OR_GREATER - return options.TypeInfoResolver is not null - ? JsonSerializer.Deserialize(span, SystemTextJsonContentSerializer.GetJsonTypeInfo(options)) - : DeserializeLineReflection(span, options); -#else - return DeserializeLineReflection(span, options); -#endif + return JsonSerializer.Deserialize(span, SystemTextJsonContentSerializer.GetJsonTypeInfo(options)); } - - /// Deserializes a JSON line using reflection-based metadata. - /// The element type to deserialize. - /// The UTF-8 encoded JSON value. - /// The serializer options to use. - /// The deserialized value. - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - internal static T? DeserializeLineReflection(ReadOnlySpan utf8Json, JsonSerializerOptions options) => - DeserializeSseDataReflection(utf8Json, options); #endif /// Deserializes a server-sent event's UTF-8 JSON data payload. /// The element type to deserialize. /// The event type, which is not surfaced by this serializer. /// The UTF-8 encoded JSON payload bytes. - /// The serializer options to use. + /// The serializer options to use. They must carry type metadata. /// The deserialized value. [SuppressMessage( "Design", @@ -192,27 +131,6 @@ internal static class SystemTextJsonStreamingDeserializer JsonSerializerOptions options) { _ = eventType; -#if NET8_0_OR_GREATER - return options.TypeInfoResolver is not null - ? JsonSerializer.Deserialize(data, SystemTextJsonContentSerializer.GetJsonTypeInfo(options)) - : DeserializeSseDataReflection(data, options); -#else - return DeserializeSseDataReflection(data, options); -#endif + return JsonSerializer.Deserialize(data, SystemTextJsonContentSerializer.GetJsonTypeInfo(options)); } - - /// Deserializes a server-sent event payload using reflection-based metadata. - /// The element type to deserialize. - /// The UTF-8 encoded JSON payload bytes. - /// The serializer options to use. - /// The deserialized value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = ReflectionFallbackJustification)] - [UnconditionalSuppressMessage("AOT", "IL3050", Justification = ReflectionFallbackJustification)] - [SuppressMessage( - "Design", - "SST2307:Generic method type parameters should be inferable from the parameters", - Justification = "Type parameter intentionally specified explicitly by callers.")] - internal static T? DeserializeSseDataReflection(ReadOnlySpan utf8Json, JsonSerializerOptions options) => - JsonSerializer.Deserialize(utf8Json, options); } diff --git a/src/Refit/ValidationApiException.cs b/src/Refit/ValidationApiException.cs index 585479ba8..835346c0f 100644 --- a/src/Refit/ValidationApiException.cs +++ b/src/Refit/ValidationApiException.cs @@ -85,31 +85,6 @@ public static ValidationApiException Create(ApiException exception) return ex; } - /// - /// Creates a new instance of a ValidationException from an existing ApiException, - /// deserializing the problem details with the serializer configured in - /// . - /// - /// An instance of an ApiException to use to build a ValidationException. - /// ValidationApiException. - internal static async Task CreateAsync(ApiException exception) - { - var ex = CreateCore(exception); - - // Deserialize through the configured IHttpContentSerializer rather than a - // hardcoded System.Text.Json instance, so problem details honor the user's - // serializer (e.g. Newtonsoft) and its settings. - using var content = new StringContent( - exception.Content!, - Encoding.UTF8, - "application/problem+json"); - ex.Content = await exception - .RefitSettings.ContentSerializer.FromHttpContentAsync(content) - .ConfigureAwait(false); - - return ex; - } - /// Validates the exception content and builds the base validation exception. /// The API exception to convert. /// A new validation exception wrapping the API exception. @@ -266,7 +241,7 @@ internal static string ReadErrorMessage(JsonElement element) => ? element.GetString()! // A String-kind element always yields a non-null string. : element.GetRawText(); - /// Reads extension data using the same inferred primitives as the System.Text.Json converter. + /// Reads extension data as inferred primitives, falling back to a cloned . /// The JSON element. /// The extension value. internal static object ReadExtensionValue(JsonElement element) => diff --git a/src/benchmarks/Refit.Benchmarks/ContentSerializerHelperBenchmarks.cs b/src/benchmarks/Refit.Benchmarks/ContentSerializerHelperBenchmarks.cs index 24be577ed..3d4040c2c 100644 --- a/src/benchmarks/Refit.Benchmarks/ContentSerializerHelperBenchmarks.cs +++ b/src/benchmarks/Refit.Benchmarks/ContentSerializerHelperBenchmarks.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Configs; @@ -33,9 +32,6 @@ public class ContentSerializerHelperBenchmarks /// A JSON object serialized and deserialized by the round-trip benchmarks. private User _user = null!; - /// The reflected property whose JSON field name is resolved. - private PropertyInfo _property = null!; - /// The JSON string deserialized by the round-trip benchmark. private string _json = null!; @@ -44,16 +40,9 @@ public class ContentSerializerHelperBenchmarks public void Setup() { _user = new() { Id = 1, Name = "Ada", Bio = "mathematician", Url = "https://x/y" }; - _property = _declaredType.GetProperty(nameof(User.Name))!; _json = System.Text.Encoding.UTF8.GetString(_serializer.SerializeToUtf8Bytes(_user)); } - /// Resolves the JSON field name for a property (attribute lookup). - /// The resolved field name length, or zero when unset. - [Benchmark] - [BenchmarkCategory("Metadata")] - public int GetFieldNameForProperty() => _serializer.GetFieldNameForProperty(_property)?.Length ?? 0; - /// Determines whether the declared type is configured for polymorphic serialization. /// 1 when polymorphic; otherwise 0. [Benchmark] diff --git a/src/benchmarks/Refit.Benchmarks/EnumHandlingBenchmarks.cs b/src/benchmarks/Refit.Benchmarks/EnumHandlingBenchmarks.cs index 28d20ed66..9f26e60f8 100644 --- a/src/benchmarks/Refit.Benchmarks/EnumHandlingBenchmarks.cs +++ b/src/benchmarks/Refit.Benchmarks/EnumHandlingBenchmarks.cs @@ -2,9 +2,7 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; using System.Runtime.CompilerServices; -using System.Text.Json; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Diagnosers; @@ -13,8 +11,7 @@ namespace Refit.Benchmarks; /// /// Allocation micro-benchmarks for enum handling: the EnumHelpers [EnumMember] value lookup and cache -/// build, the undefined-value numeric formatting, the CamelCaseStringEnumConverter name helpers and -/// serialized-name dictionary construction, and a JSON round-trip through the camelCase enum converter. +/// build, and the undefined-value numeric formatting. /// [System.Diagnostics.DebuggerDisplay("{ToString(),nq}")] [MemoryDiagnoser] @@ -36,29 +33,10 @@ public class EnumHandlingBenchmarks /// An undefined enum value formatted through the numeric path. private readonly QuerySort _undefinedValue = (QuerySort)999; - /// A defined enum value serialized through the converter. - private readonly QuerySort _definedValue = QuerySort.Name; - - /// A Pascal-cased name converted to camelCase. - private readonly string _pascalName = "DateDescending"; - - /// The enum field carrying an [EnumMember] override. - private FieldInfo _memberField = null!; - - /// Options carrying the camelCase enum converter used by the round-trip benchmarks. - private JsonSerializerOptions _options = null!; - - /// The serialized camelCase name deserialized by the round-trip benchmark. - private string _serializedName = null!; - - /// Resolves the reflected field and serializer options before the benchmarks run. + /// Registers the reflection support that supplies the [EnumMember] lookup. + [MethodImpl(MethodImplOptions.AggressiveInlining)] [GlobalSetup] - public void Setup() - { - _memberField = _enumType.GetField(nameof(QuerySort.DateDescending))!; - _options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions(); - _serializedName = JsonSerializer.Serialize(_definedValue, _options); - } + public static void Setup() => ReflectionSupport.EnsureRegistered(); /// Looks up the cached [EnumMember] value for a member that declares one. /// The looked-up value length. @@ -81,18 +59,7 @@ public int GetEnumMemberValueNoMember() => [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Build")] - public int CreateEnumMemberValueMap() => EnumHelpers.CreateEnumMemberValueMap(_enumType).Count; - - /// Constructs the camelCase enum converter, building all three serialized-name maps from a single field scan. - /// The names-to-values entry count, forcing the maps to be built. - [Benchmark] - [BenchmarkCategory("Build")] - public int ConstructEnumConverter() - { - // Reading a shared field anchors this construction benchmark to the instance so BenchmarkDotNet can invoke it. - _ = _enumType; - return new CamelCaseStringEnumConverter.EnumConverter().MapEntryCount; - } + public int CreateEnumMemberValueMap() => EnumMemberValues.CreateEnumMemberValueMap(_enumType).Count; /// Formats an undefined enum value through the numeric backing-type path. /// The formatted value length. @@ -100,31 +67,4 @@ public int ConstructEnumConverter() [Benchmark] [BenchmarkCategory("Format")] public int FormatNumericValue() => EnumHelpers.Info.FormatNumericValue(_undefinedValue).Length; - - /// Converts a Pascal-cased name to camelCase. - /// The converted value length. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [Benchmark] - [BenchmarkCategory("Format")] - public int ToCamelCase() => CamelCaseStringEnumConverter.ToCamelCase(_pascalName).Length; - - /// Resolves the preferred serialized name for an enum field. - /// The resolved name length. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [Benchmark] - [BenchmarkCategory("Format")] - public int GetPreferredSerializedName() => CamelCaseStringEnumConverter.GetPreferredSerializedName(_memberField).Length; - - /// Serializes a defined enum value through the camelCase converter. - /// The serialized name length. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [Benchmark] - [BenchmarkCategory("RoundTrip")] - public int SerializeEnum() => JsonSerializer.Serialize(_definedValue, _options).Length; - - /// Deserializes a camelCase name back to its enum value through the converter. - /// The deserialized enum value as an integer. - [Benchmark] - [BenchmarkCategory("RoundTrip")] - public int DeserializeEnum() => (int)JsonSerializer.Deserialize(_serializedName, _options); } diff --git a/src/benchmarks/Refit.Benchmarks/FormBodySerializationBenchmark.cs b/src/benchmarks/Refit.Benchmarks/FormBodySerializationBenchmark.cs index 2551add4b..9c6d828a0 100644 --- a/src/benchmarks/Refit.Benchmarks/FormBodySerializationBenchmark.cs +++ b/src/benchmarks/Refit.Benchmarks/FormBodySerializationBenchmark.cs @@ -39,12 +39,12 @@ public void Setup() _fields = [ - new(static b => b.FirstName, "FirstName", "first_name", null, null, null, false), - new(static b => b.LastName, "LastName", "last_name", null, null, null, false), - new(static b => b.Email, "Email", null, null, null, null, false), - new(static b => b.Age, "Age", null, null, null, null, false), - new(static b => b.Note, "Note", null, null, null, null, true), - new(static b => b.Roles, "Roles", null, null, null, CollectionFormat.Multi, false) + new(static b => b.FirstName, "FirstName", new("first_name", null, null, null), null, null, null, false), + new(static b => b.LastName, "LastName", new("last_name", null, null, null), null, null, null, false), + new(static b => b.Email, "Email", default, null, null, null, false), + new(static b => b.Age, "Age", default, null, null, null, false), + new(static b => b.Note, "Note", default, null, null, null, true), + new(static b => b.Roles, "Roles", default, null, null, CollectionFormat.Multi, false) ]; VerifyUnrolledMatchesDescriptor(); diff --git a/src/benchmarks/Refit.Benchmarks/FormValueMappingBenchmarks.cs b/src/benchmarks/Refit.Benchmarks/FormValueMappingBenchmarks.cs index 224ee70d1..5ab9c8f1e 100644 --- a/src/benchmarks/Refit.Benchmarks/FormValueMappingBenchmarks.cs +++ b/src/benchmarks/Refit.Benchmarks/FormValueMappingBenchmarks.cs @@ -54,12 +54,12 @@ public void Setup() _fields = [ - new(static b => b.FirstName, "FirstName", "first_name", null, null, null, false), - new(static b => b.LastName, "LastName", "last_name", null, null, null, false), - new(static b => b.Email, "Email", null, null, null, null, false), - new(static b => b.Age, "Age", null, null, null, null, false), - new(static b => b.Note, "Note", null, null, null, null, true), - new(static b => b.Roles, "Roles", null, null, null, CollectionFormat.Multi, false), + new(static b => b.FirstName, "FirstName", new("first_name", null, null, null), null, null, null, false), + new(static b => b.LastName, "LastName", new("last_name", null, null, null), null, null, null, false), + new(static b => b.Email, "Email", default, null, null, null, false), + new(static b => b.Age, "Age", default, null, null, null, false), + new(static b => b.Note, "Note", default, null, null, null, true), + new(static b => b.Roles, "Roles", default, null, null, CollectionFormat.Multi, false), ]; } @@ -75,7 +75,7 @@ public void Setup() [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Mapping")] - public int DescriptorCreate() => Count(FormValueMultimap.CreateFromFields(_body, _fields, _settings)); + public int DescriptorCreate() => Count(FormValueMultimap.CreateFromFields(_body, _fields, _settings, ContentSerializerNameStyle.SystemTextJson)); /// Joins a collection of values with the comma delimiter through the shared join helper. /// The joined value length. diff --git a/src/benchmarks/Refit.Benchmarks/ParameterAttributeProviderBenchmarks.cs b/src/benchmarks/Refit.Benchmarks/ParameterAttributeProviderBenchmarks.cs index 283c5f845..d8e2597ba 100644 --- a/src/benchmarks/Refit.Benchmarks/ParameterAttributeProviderBenchmarks.cs +++ b/src/benchmarks/Refit.Benchmarks/ParameterAttributeProviderBenchmarks.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; using System.Runtime.CompilerServices; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Configs; @@ -54,7 +53,7 @@ public void Setup() [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Construction")] - public ICustomAttributeProvider CreateSingleTypeProvider() => + public IParameterAttributeProvider CreateSingleTypeProvider() => new GeneratedSingleTypeParameterAttributeProvider(_attributeType, [new QueryAttribute()]); /// Builds the dictionary-backed provider for the same one-attribute parameter. @@ -62,7 +61,7 @@ public ICustomAttributeProvider CreateSingleTypeProvider() => [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark(Baseline = true)] [BenchmarkCategory("Construction")] - public ICustomAttributeProvider CreateManyTypeProvider() => + public IParameterAttributeProvider CreateManyTypeProvider() => new GeneratedParameterAttributeProvider(new Dictionary { [_attributeType] = [new QueryAttribute()], }); /// Resolves the query attribute through the single-type provider. diff --git a/src/benchmarks/Refit.Benchmarks/RequestPathBuildingBenchmarks.cs b/src/benchmarks/Refit.Benchmarks/RequestPathBuildingBenchmarks.cs index 30f6a9171..6bade3896 100644 --- a/src/benchmarks/Refit.Benchmarks/RequestPathBuildingBenchmarks.cs +++ b/src/benchmarks/Refit.Benchmarks/RequestPathBuildingBenchmarks.cs @@ -124,7 +124,7 @@ public int BuildPathFormattable() => [Benchmark] [BenchmarkCategory("Path")] public int RoundTripEscapePath() => - GeneratedRequestRunner.RoundTripEscapePath(_catchAllValue, _settings, typeof(string), typeof(string)).Length; + GeneratedRequestRunner.RoundTripEscapePath(_catchAllValue, _settings, GeneratedParameterAttributeProvider.Empty, typeof(string)).Length; /// Assembles a relative URI under RFC 3986 resolution. /// The relative URI string length. @@ -191,7 +191,7 @@ public int AddFormattedCollectionCsv() "ids", CollectionFormat.Csv, false, - (typeof(int[]), typeof(int[]), typeof(int[]))); + (typeof(int[]), GeneratedParameterAttributeProvider.Empty, typeof(int[]))); return builder.Build().Length; } @@ -209,7 +209,7 @@ public int AddFormattedCollectionMulti() "ids", CollectionFormat.Multi, false, - (typeof(int[]), typeof(int[]), typeof(int[]))); + (typeof(int[]), GeneratedParameterAttributeProvider.Empty, typeof(int[]))); return builder.Build().Length; } diff --git a/src/benchmarks/Refit.Benchmarks/UrlParameterFormattingBenchmarks.cs b/src/benchmarks/Refit.Benchmarks/UrlParameterFormattingBenchmarks.cs index 01ccf0a71..59c666c4f 100644 --- a/src/benchmarks/Refit.Benchmarks/UrlParameterFormattingBenchmarks.cs +++ b/src/benchmarks/Refit.Benchmarks/UrlParameterFormattingBenchmarks.cs @@ -55,42 +55,42 @@ public class UrlParameterFormattingBenchmarks [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Value")] - public int FormatString() => (_valueFormatter.Format("widgets and gadgets", typeof(string), typeof(string)) ?? string.Empty).Length; + public int FormatString() => (_valueFormatter.Format("widgets and gadgets", GeneratedParameterAttributeProvider.Empty, typeof(string)) ?? string.Empty).Length; /// Formats an integer value (boxed through the invariant string.Format path). /// The formatted value length. [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Value")] - public int FormatInt() => (_valueFormatter.Format(SampleInteger, typeof(int), typeof(int)) ?? string.Empty).Length; + public int FormatInt() => (_valueFormatter.Format(SampleInteger, GeneratedParameterAttributeProvider.Empty, typeof(int)) ?? string.Empty).Length; /// Formats an enum value with no [EnumMember] override. /// The formatted value length. [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Value")] - public int FormatEnumPlain() => (_valueFormatter.Format(QuerySort.Name, typeof(QuerySort), typeof(QuerySort)) ?? string.Empty).Length; + public int FormatEnumPlain() => (_valueFormatter.Format(QuerySort.Name, GeneratedParameterAttributeProvider.Empty, typeof(QuerySort)) ?? string.Empty).Length; /// Formats an enum value carrying an [EnumMember] override (exercises the enum-member cache). /// The formatted value length. [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Value")] - public int FormatEnumMember() => (_valueFormatter.Format(QuerySort.DateDescending, typeof(QuerySort), typeof(QuerySort)) ?? string.Empty).Length; + public int FormatEnumMember() => (_valueFormatter.Format(QuerySort.DateDescending, GeneratedParameterAttributeProvider.Empty, typeof(QuerySort)) ?? string.Empty).Length; /// Formats a value. /// The formatted value length. [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Value")] - public int FormatDateTimeOffset() => (_valueFormatter.Format(_timestamp, typeof(DateTimeOffset), typeof(DateTimeOffset)) ?? string.Empty).Length; + public int FormatDateTimeOffset() => (_valueFormatter.Format(_timestamp, GeneratedParameterAttributeProvider.Empty, typeof(DateTimeOffset)) ?? string.Empty).Length; /// Formats a value. /// The formatted value length. [MethodImpl(MethodImplOptions.AggressiveInlining)] [Benchmark] [BenchmarkCategory("Value")] - public int FormatGuid() => (_valueFormatter.Format(_guid, typeof(Guid), typeof(Guid)) ?? string.Empty).Length; + public int FormatGuid() => (_valueFormatter.Format(_guid, GeneratedParameterAttributeProvider.Empty, typeof(Guid)) ?? string.Empty).Length; /// Formats a key through the pass-through default key formatter (baseline). /// The formatted key length. diff --git a/src/examples/Documentation/Aot/NativeClient/NativeClient.csproj b/src/examples/Documentation/Aot/NativeClient/NativeClient.csproj index d699405f5..7da2b0b6d 100644 --- a/src/examples/Documentation/Aot/NativeClient/NativeClient.csproj +++ b/src/examples/Documentation/Aot/NativeClient/NativeClient.csproj @@ -12,6 +12,7 @@ + diff --git a/src/examples/Documentation/Bodies/ContentOnlySerializer.cs b/src/examples/Documentation/Bodies/ContentOnlySerializer.cs index 92441c5a6..de64e8728 100644 --- a/src/examples/Documentation/Bodies/ContentOnlySerializer.cs +++ b/src/examples/Documentation/Bodies/ContentOnlySerializer.cs @@ -1,7 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; using System.Runtime.CompilerServices; namespace Refit.Documentation; @@ -30,10 +29,4 @@ internal sealed class ContentOnlySerializer : IHttpContentSerializer /// The deserialized reply. [MethodImpl(MethodImplOptions.AggressiveInlining)] public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken) => _serializer.FromHttpContentAsync(content, cancellationToken); - - /// Delegates the explicit attribute-based naming hook. - /// The known property to inspect. - /// The explicit JSON name, or null. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string? GetFieldNameForProperty(PropertyInfo propertyInfo) => _serializer.GetFieldNameForProperty(propertyInfo); } diff --git a/src/examples/Documentation/Clients/Reflection/Reflection.csproj b/src/examples/Documentation/Clients/Reflection/Reflection.csproj index 223b4fd24..7458f7d5f 100644 --- a/src/examples/Documentation/Clients/Reflection/Reflection.csproj +++ b/src/examples/Documentation/Clients/Reflection/Reflection.csproj @@ -11,6 +11,7 @@ + diff --git a/src/examples/Documentation/Content/ContentSample.cs b/src/examples/Documentation/Content/ContentSample.cs index f445fce13..2f6844629 100644 --- a/src/examples/Documentation/Content/ContentSample.cs +++ b/src/examples/Documentation/Content/ContentSample.cs @@ -24,7 +24,6 @@ internal static async Task RunAsync() Person person = new(1, "Ada"); await CheckLinesAsync(serializer, person); await CheckStreamingAsync(serializer, person); - CheckConverter(person); await CheckAdapterAsync(person); } @@ -132,45 +131,6 @@ private static async Task CheckStreamLifetimeAsync(TSerializer stre SampleCheck.Equal(true, early.CanRead); } - /// Checks direct converter reads and runtime-type writes. - /// The runtime object written using generated metadata. - private static void CheckConverter(Person person) - { - ObjectToInferredTypesConverter converter = new(); - Utf8JsonReader reader = new("1"u8); - _ = reader.Read(); - object? inferred = converter.Read(ref reader, typeof(object), Options); - Console.WriteLine(inferred!.GetType().Name); // Int64 - SampleCheck.Equal(1L, (long)inferred); - string[] tokens = ["true", "false", "1.5", "\"2026-01-01T00:00:00\"", "\"Ada\"", "{}", "[]", "null"]; - Type[] expected = [typeof(bool), typeof(bool), typeof(double), typeof(DateTime), typeof(string), typeof(JsonElement), typeof(JsonElement), typeof(JsonElement)]; - object[] expectedValues = [true, false, 1.5, new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Unspecified), "Ada", JsonValueKind.Object, JsonValueKind.Array, JsonValueKind.Null]; - for (int index = 0; index < tokens.Length; index++) - { - Utf8JsonReader tokenReader = new(Encoding.UTF8.GetBytes(tokens[index])); - _ = tokenReader.Read(); - object? value = converter.Read(ref tokenReader, typeof(object), Options); - SampleCheck.Equal(expected[index], value!.GetType()); - SampleCheck.Equal(expectedValues[index], value is JsonElement element ? element.ValueKind : value); - } - - using MemoryStream buffer = new(); - using (Utf8JsonWriter writer = new(buffer)) - { - converter.Write(writer, person, Options); - } - - Console.WriteLine(Encoding.UTF8.GetString(buffer.ToArray())); - SampleCheck.Equal(PersonJson, Encoding.UTF8.GetString(buffer.ToArray())); - using MemoryStream emptyObject = new(); - using (Utf8JsonWriter writer = new(emptyObject)) - { - converter.Write(writer, new(), Options); - } - - SampleCheck.Equal("{}", Encoding.UTF8.GetString(emptyObject.ToArray())); - } - /// Checks compile-time adapter discovery and a single deferred send. /// The expected reply. /// Completion of the adapter check. diff --git a/src/examples/Documentation/Errors/Errors.cs b/src/examples/Documentation/Errors/Errors.cs index c82ec0dd7..a8614a9e8 100644 --- a/src/examples/Documentation/Errors/Errors.cs +++ b/src/examples/Documentation/Errors/Errors.cs @@ -127,22 +127,16 @@ private static void ReadProblem(ApiException error) SampleCheck.Equal("sample", problem?.Extensions["trace"].ToString()); } - /// Reproduces the generated metadata failure for the extension-data property. - /// Completion after the exact serializer exception is verified. - /// The expected metadata failure does not occur. + /// Reads a problem document with generated metadata, which once failed on the extension-data property. + /// Completion after the problem document is verified. private static async Task CheckProblemMetadataAsync() { using HttpContent content = new StringContent(ProblemJson); - try - { - _ = await Settings.ContentSerializer.FromHttpContentAsync(content); - throw new InvalidOperationException("Generated ProblemDetails metadata should reproduce the failure."); - } - catch (InvalidOperationException error) - { - Console.WriteLine(error.Message); - SampleCheck.Equal("The extension data property 'Extensions' on type 'Refit.ProblemDetails' cannot bind with a parameter in the deserialization constructor.", error.Message); - } + ProblemDetails? problem = await Settings.ContentSerializer.FromHttpContentAsync(content); + Console.WriteLine(problem?.Title); + + SampleCheck.Equal("Invalid name", problem?.Title); + SampleCheck.Equal((int)HttpStatusCode.BadRequest, problem?.Status); } /// Checks public exception constructors and HTTP/validation factories. diff --git a/src/examples/Documentation/JsonContexts/OrderReadsJsonContext.cs b/src/examples/Documentation/JsonContexts/OrderReadsJsonContext.cs index f4043ce67..ac386fa89 100644 --- a/src/examples/Documentation/JsonContexts/OrderReadsJsonContext.cs +++ b/src/examples/Documentation/JsonContexts/OrderReadsJsonContext.cs @@ -7,6 +7,6 @@ namespace Refit.Documentation.JsonContexts; /// Metadata that describes Order and nothing else, so NewOrder has no metadata. -[JsonSourceGenerationOptions(JsonSerializerDefaults.Web)] +[JsonSourceGenerationOptions(JsonSerializerDefaults.Web, UseStringEnumConverter = true)] [JsonSerializable(typeof(Order))] internal sealed partial class OrderReadsJsonContext : JsonSerializerContext; diff --git a/src/examples/Documentation/JsonContexts/OrderStatus.cs b/src/examples/Documentation/JsonContexts/OrderStatus.cs index adb1079dd..0ecaa5f8c 100644 --- a/src/examples/Documentation/JsonContexts/OrderStatus.cs +++ b/src/examples/Documentation/JsonContexts/OrderStatus.cs @@ -1,12 +1,9 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Text.Json.Serialization; - namespace Refit.Documentation.JsonContexts; -/// Where an order is in the shop's fulfilment process. -[JsonConverter(typeof(JsonStringEnumConverter))] +/// Where an order is in the shop's fulfilment process. The contexts write it as a string through UseStringEnumConverter. internal enum OrderStatus { /// The shop has accepted the order and has not sent it. diff --git a/src/examples/Documentation/JsonContexts/OrdersJsonContext.cs b/src/examples/Documentation/JsonContexts/OrdersJsonContext.cs index a738a3d33..3e3ea060a 100644 --- a/src/examples/Documentation/JsonContexts/OrdersJsonContext.cs +++ b/src/examples/Documentation/JsonContexts/OrdersJsonContext.cs @@ -7,7 +7,7 @@ namespace Refit.Documentation.JsonContexts; /// Generated JSON metadata for every request and reply type of the orders API. -[JsonSourceGenerationOptions(JsonSerializerDefaults.Web)] +[JsonSourceGenerationOptions(JsonSerializerDefaults.Web, UseStringEnumConverter = true)] [JsonSerializable(typeof(Order))] [JsonSerializable(typeof(List))] [JsonSerializable(typeof(NewOrder))] diff --git a/src/examples/Documentation/JsonContexts/UnconfiguredOrdersJsonContext.cs b/src/examples/Documentation/JsonContexts/UnconfiguredOrdersJsonContext.cs index fed0809db..f4ef24a74 100644 --- a/src/examples/Documentation/JsonContexts/UnconfiguredOrdersJsonContext.cs +++ b/src/examples/Documentation/JsonContexts/UnconfiguredOrdersJsonContext.cs @@ -6,6 +6,7 @@ namespace Refit.Documentation.JsonContexts; /// The orders metadata without JsonSourceGenerationOptions, so System.Text.Json's own defaults apply. +[JsonSourceGenerationOptions(UseStringEnumConverter = true)] [JsonSerializable(typeof(Order))] [JsonSerializable(typeof(List))] [JsonSerializable(typeof(NewOrder))] diff --git a/src/examples/Documentation/Pages/advanced-index/advanced-index.csproj b/src/examples/Documentation/Pages/advanced-index/advanced-index.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/advanced-index/advanced-index.csproj +++ b/src/examples/Documentation/Pages/advanced-index/advanced-index.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/advanced-method-metadata/advanced-method-metadata.csproj b/src/examples/Documentation/Pages/advanced-method-metadata/advanced-method-metadata.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/advanced-method-metadata/advanced-method-metadata.csproj +++ b/src/examples/Documentation/Pages/advanced-method-metadata/advanced-method-metadata.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/advanced-query-builder/advanced-query-builder.csproj b/src/examples/Documentation/Pages/advanced-query-builder/advanced-query-builder.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/advanced-query-builder/advanced-query-builder.csproj +++ b/src/examples/Documentation/Pages/advanced-query-builder/advanced-query-builder.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/advanced-request-helpers/advanced-request-helpers.csproj b/src/examples/Documentation/Pages/advanced-request-helpers/advanced-request-helpers.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/advanced-request-helpers/advanced-request-helpers.csproj +++ b/src/examples/Documentation/Pages/advanced-request-helpers/advanced-request-helpers.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/aot/aot.csproj b/src/examples/Documentation/Pages/aot/aot.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/aot/aot.csproj +++ b/src/examples/Documentation/Pages/aot/aot.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/clients-creation/clients-creation.csproj b/src/examples/Documentation/Pages/clients-creation/clients-creation.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/clients-creation/clients-creation.csproj +++ b/src/examples/Documentation/Pages/clients-creation/clients-creation.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/clients-dependency-injection/clients-dependency-injection.csproj b/src/examples/Documentation/Pages/clients-dependency-injection/clients-dependency-injection.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/clients-dependency-injection/clients-dependency-injection.csproj +++ b/src/examples/Documentation/Pages/clients-dependency-injection/clients-dependency-injection.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/clients-index/clients-index.csproj b/src/examples/Documentation/Pages/clients-index/clients-index.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/clients-index/clients-index.csproj +++ b/src/examples/Documentation/Pages/clients-index/clients-index.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/clients-request-builders/clients-request-builders.csproj b/src/examples/Documentation/Pages/clients-request-builders/clients-request-builders.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/clients-request-builders/clients-request-builders.csproj +++ b/src/examples/Documentation/Pages/clients-request-builders/clients-request-builders.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/clients-resilience/clients-resilience.csproj b/src/examples/Documentation/Pages/clients-resilience/clients-resilience.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/clients-resilience/clients-resilience.csproj +++ b/src/examples/Documentation/Pages/clients-resilience/clients-resilience.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/clients-settings/clients-settings.csproj b/src/examples/Documentation/Pages/clients-settings/clients-settings.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/clients-settings/clients-settings.csproj +++ b/src/examples/Documentation/Pages/clients-settings/clients-settings.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/clients-telemetry/clients-telemetry.csproj b/src/examples/Documentation/Pages/clients-telemetry/clients-telemetry.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/clients-telemetry/clients-telemetry.csproj +++ b/src/examples/Documentation/Pages/clients-telemetry/clients-telemetry.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/index/index.csproj b/src/examples/Documentation/Pages/index/index.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/index/index.csproj +++ b/src/examples/Documentation/Pages/index/index.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-bodies/requests-bodies.csproj b/src/examples/Documentation/Pages/requests-bodies/requests-bodies.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-bodies/requests-bodies.csproj +++ b/src/examples/Documentation/Pages/requests-bodies/requests-bodies.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-headers/requests-headers.csproj b/src/examples/Documentation/Pages/requests-headers/requests-headers.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-headers/requests-headers.csproj +++ b/src/examples/Documentation/Pages/requests-headers/requests-headers.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-index/requests-index.csproj b/src/examples/Documentation/Pages/requests-index/requests-index.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-index/requests-index.csproj +++ b/src/examples/Documentation/Pages/requests-index/requests-index.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-multipart/requests-multipart.csproj b/src/examples/Documentation/Pages/requests-multipart/requests-multipart.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-multipart/requests-multipart.csproj +++ b/src/examples/Documentation/Pages/requests-multipart/requests-multipart.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-queries/requests-queries.csproj b/src/examples/Documentation/Pages/requests-queries/requests-queries.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-queries/requests-queries.csproj +++ b/src/examples/Documentation/Pages/requests-queries/requests-queries.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-query-converters/requests-query-converters.csproj b/src/examples/Documentation/Pages/requests-query-converters/requests-query-converters.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-query-converters/requests-query-converters.csproj +++ b/src/examples/Documentation/Pages/requests-query-converters/requests-query-converters.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-query-formatters/requests-query-formatters.csproj b/src/examples/Documentation/Pages/requests-query-formatters/requests-query-formatters.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-query-formatters/requests-query-formatters.csproj +++ b/src/examples/Documentation/Pages/requests-query-formatters/requests-query-formatters.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-request-context/requests-request-context.csproj b/src/examples/Documentation/Pages/requests-request-context/requests-request-context.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-request-context/requests-request-context.csproj +++ b/src/examples/Documentation/Pages/requests-request-context/requests-request-context.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/requests-routes/requests-routes.csproj b/src/examples/Documentation/Pages/requests-routes/requests-routes.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/requests-routes/requests-routes.csproj +++ b/src/examples/Documentation/Pages/requests-routes/requests-routes.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/results-adapters/results-adapters.csproj b/src/examples/Documentation/Pages/results-adapters/results-adapters.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/results-adapters/results-adapters.csproj +++ b/src/examples/Documentation/Pages/results-adapters/results-adapters.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/results-errors/results-errors.csproj b/src/examples/Documentation/Pages/results-errors/results-errors.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/results-errors/results-errors.csproj +++ b/src/examples/Documentation/Pages/results-errors/results-errors.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/results-index/results-index.csproj b/src/examples/Documentation/Pages/results-index/results-index.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/results-index/results-index.csproj +++ b/src/examples/Documentation/Pages/results-index/results-index.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/results-paging/results-paging.csproj b/src/examples/Documentation/Pages/results-paging/results-paging.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/results-paging/results-paging.csproj +++ b/src/examples/Documentation/Pages/results-paging/results-paging.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/results-responses/results-responses.csproj b/src/examples/Documentation/Pages/results-responses/results-responses.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/results-responses/results-responses.csproj +++ b/src/examples/Documentation/Pages/results-responses/results-responses.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/results-return-types/results-return-types.csproj b/src/examples/Documentation/Pages/results-return-types/results-return-types.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/results-return-types/results-return-types.csproj +++ b/src/examples/Documentation/Pages/results-return-types/results-return-types.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/results-streaming/results-streaming.csproj b/src/examples/Documentation/Pages/results-streaming/results-streaming.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/results-streaming/results-streaming.csproj +++ b/src/examples/Documentation/Pages/results-streaming/results-streaming.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/serialization-content/serialization-content.csproj b/src/examples/Documentation/Pages/serialization-content/serialization-content.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/serialization-content/serialization-content.csproj +++ b/src/examples/Documentation/Pages/serialization-content/serialization-content.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/serialization-index/serialization-index.csproj b/src/examples/Documentation/Pages/serialization-index/serialization-index.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/serialization-index/serialization-index.csproj +++ b/src/examples/Documentation/Pages/serialization-index/serialization-index.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/serialization-json/serialization-json.csproj b/src/examples/Documentation/Pages/serialization-json/serialization-json.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/serialization-json/serialization-json.csproj +++ b/src/examples/Documentation/Pages/serialization-json/serialization-json.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/serialization-newtonsoft-json/serialization-newtonsoft-json.csproj b/src/examples/Documentation/Pages/serialization-newtonsoft-json/serialization-newtonsoft-json.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/serialization-newtonsoft-json/serialization-newtonsoft-json.csproj +++ b/src/examples/Documentation/Pages/serialization-newtonsoft-json/serialization-newtonsoft-json.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/serialization-xml/serialization-xml.csproj b/src/examples/Documentation/Pages/serialization-xml/serialization-xml.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/serialization-xml/serialization-xml.csproj +++ b/src/examples/Documentation/Pages/serialization-xml/serialization-xml.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/testing-faults/testing-faults.csproj b/src/examples/Documentation/Pages/testing-faults/testing-faults.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/testing-faults/testing-faults.csproj +++ b/src/examples/Documentation/Pages/testing-faults/testing-faults.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/testing-index/testing-index.csproj b/src/examples/Documentation/Pages/testing-index/testing-index.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/testing-index/testing-index.csproj +++ b/src/examples/Documentation/Pages/testing-index/testing-index.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/testing-replies/testing-replies.csproj b/src/examples/Documentation/Pages/testing-replies/testing-replies.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/testing-replies/testing-replies.csproj +++ b/src/examples/Documentation/Pages/testing-replies/testing-replies.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/testing-response-stubs/testing-response-stubs.csproj b/src/examples/Documentation/Pages/testing-response-stubs/testing-response-stubs.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/testing-response-stubs/testing-response-stubs.csproj +++ b/src/examples/Documentation/Pages/testing-response-stubs/testing-response-stubs.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/testing-routes/testing-routes.csproj b/src/examples/Documentation/Pages/testing-routes/testing-routes.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/testing-routes/testing-routes.csproj +++ b/src/examples/Documentation/Pages/testing-routes/testing-routes.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/testing-streaming/testing-streaming.csproj b/src/examples/Documentation/Pages/testing-streaming/testing-streaming.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/testing-streaming/testing-streaming.csproj +++ b/src/examples/Documentation/Pages/testing-streaming/testing-streaming.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/testing-verification/testing-verification.csproj b/src/examples/Documentation/Pages/testing-verification/testing-verification.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/testing-verification/testing-verification.csproj +++ b/src/examples/Documentation/Pages/testing-verification/testing-verification.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Pages/why-refit/why-refit.csproj b/src/examples/Documentation/Pages/why-refit/why-refit.csproj index 1f3697dcf..17a3748ac 100644 --- a/src/examples/Documentation/Pages/why-refit/why-refit.csproj +++ b/src/examples/Documentation/Pages/why-refit/why-refit.csproj @@ -9,6 +9,7 @@ + diff --git a/src/examples/Documentation/Queries/Formatters.cs b/src/examples/Documentation/Queries/Formatters.cs index 7314b73fd..4e09c7009 100644 --- a/src/examples/Documentation/Queries/Formatters.cs +++ b/src/examples/Documentation/Queries/Formatters.cs @@ -65,8 +65,8 @@ internal static async Task RunAsync(SampleHost host) /// The date used by both URL and form examples. private static void CheckDirectFormats(DefaultUrlParameterFormatter values, DateTime day) { - string? general = values.Format(day, typeof(DateTime), typeof(DateTime)); - string? contained = values.Format(day, typeof(DateTime), typeof(DateFilter)); + string? general = values.Format(day, GeneratedParameterAttributeProvider.Empty, typeof(DateTime)); + string? contained = values.Format(day, GeneratedParameterAttributeProvider.Empty, typeof(DateFilter)); DefaultFormUrlEncodedParameterFormatter formValues = new(); string? formDate = formValues.Format(day, DateFormat); string? omitted = formValues.Format(null, null); @@ -78,7 +78,7 @@ private static void CheckDirectFormats(DefaultUrlParameterFormatter values, Date SampleCheck.Equal(DayText, contained); SampleCheck.Equal(DayText, formDate); SampleCheck.Equal(null, omitted); - SampleCheck.Equal(null, values.Format(null, typeof(DateTime), typeof(DateTime))); + SampleCheck.Equal(null, values.Format(null, GeneratedParameterAttributeProvider.Empty, typeof(DateTime))); SampleCheck.Equal("unchanged", formValues.Format("unchanged", DateFormat)); SampleCheck.Equal("1", formValues.Format(1, " ")); } diff --git a/src/examples/Documentation/Queries/YesNoFormatter.cs b/src/examples/Documentation/Queries/YesNoFormatter.cs index 13416d13c..09f2dbf7f 100644 --- a/src/examples/Documentation/Queries/YesNoFormatter.cs +++ b/src/examples/Documentation/Queries/YesNoFormatter.cs @@ -1,9 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. - -using System.Reflection; - namespace Refit.Documentation; /// Uses yes and no for booleans and declines unsupported values. @@ -14,7 +11,7 @@ internal sealed class YesNoFormatter : IUrlParameterFormatter /// The source metadata; boolean formatting does not inspect its attributes. /// The declared source type; this formatter chooses from the actual boolean value. /// The yes or no text for a boolean, or null for an unsupported value. - public string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type) => value switch + public string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type) => value switch { true => "yes", false => "no", diff --git a/src/examples/Documentation/RuntimeHelpers/BodySample.cs b/src/examples/Documentation/RuntimeHelpers/BodySample.cs index dc57d85b1..43b7b8b10 100644 --- a/src/examples/Documentation/RuntimeHelpers/BodySample.cs +++ b/src/examples/Documentation/RuntimeHelpers/BodySample.cs @@ -25,21 +25,22 @@ internal static async Task RunAsync() FormBody body = new(); const string formPrefix = "form."; - FormField count = new(static value => value.Count, nameof(FormBody.Count), nameof(count), formPrefix, "D3", null, false); - FormField note = new(static value => value.Note, nameof(FormBody.Note), "note", null, null, CollectionFormat.Csv, true); + FormField count = new(static value => value.Count, nameof(FormBody.Count), new(nameof(count), null, null, null), formPrefix, "D3", null, false); + FormField note = new(static value => value.Note, nameof(FormBody.Note), new("note", null, null, null), null, null, CollectionFormat.Csv, true); FormField[] fields = [count, note]; using HttpContent form = GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, fields); string formText = await form.ReadAsStringAsync(); - string? fieldName = count.ResolveFieldName(settings.UrlParameterKeyFormatter); + string? fieldName = count.ResolveFieldName(settings.UrlParameterKeyFormatter, ContentSerializerNameStyle.SystemTextJson); Check.Require(formText == "form.count=012¬e=" && fieldName == "form.count", "Descriptors apply naming, formats, and null serialization."); Check.Require(count.Getter(body) is int number && number == SampleValues.Count, "The getter reads the declared property."); - Check.Require(count.ClrName == nameof(FormBody.Count) && count.ExplicitName == nameof(count), "The descriptor retains both names."); + Check.Require(count.ClrName == nameof(FormBody.Count) && count.Names.ExplicitName == nameof(count), "The descriptor retains both names."); Check.Require(count.PrefixSegment == formPrefix && count.Format == "D3", "The descriptor retains prefix and format."); Check.Require(count.CollectionFormat is null && !count.SerializeNull, "The descriptor retains collection and null policy."); Check.Require(note.CollectionFormat == CollectionFormat.Csv && note.SerializeNull, "Explicit descriptor collection and null policies are retained."); - FormField unaliased = new(static value => value.Count, nameof(FormBody.Count), null, formPrefix, null, null, false); - Check.Require(unaliased.ResolveFieldName(new CamelCaseUrlParameterKeyFormatter()) == "form.count", "Unaliased fields use the supplied key formatter before adding their prefix."); + FormField unaliased = new(static value => value.Count, nameof(FormBody.Count), default, formPrefix, null, null, false); + string? unaliasedName = unaliased.ResolveFieldName(new CamelCaseUrlParameterKeyFormatter(), ContentSerializerNameStyle.SystemTextJson); + Check.Require(unaliasedName == "form.count", "Unaliased fields use the supplied key formatter before adding their prefix."); Check.Require(GeneratedRequestRunner.CanUnrollForm(body) && !GeneratedRequestRunner.CanUnrollForm("text"), "Only plain objects enter the unrolled path."); using HttpContent raw = GeneratedRequestRunner.CreateBodyContent(settings, "plain text", BodySerializationMethod.Default, streamBody: false); diff --git a/src/examples/Documentation/RuntimeHelpers/PathSample.cs b/src/examples/Documentation/RuntimeHelpers/PathSample.cs index 6bdb8ab9c..50f35f650 100644 --- a/src/examples/Documentation/RuntimeHelpers/PathSample.cs +++ b/src/examples/Documentation/RuntimeHelpers/PathSample.cs @@ -112,7 +112,7 @@ private static void CheckFormatting(RefitSettings settings) (typeof(int[]), GeneratedParameterAttributeProvider.Empty, typeof(int[]))); Check.Require(query.Build() == "/items?ids=1%2C2", "Collection properties use two formatting passes."); GeneratedQueryStringBuilder multi = new(unchangedPath); - (Type, System.Reflection.ICustomAttributeProvider, Type) formatting = (typeof(int[]), GeneratedParameterAttributeProvider.Empty, typeof(int[])); + (Type, IParameterAttributeProvider, Type) formatting = (typeof(int[]), GeneratedParameterAttributeProvider.Empty, typeof(int[])); GeneratedRequestRunner.AddFormattedCollectionProperty(ref multi, settings, null, "absent", CollectionFormat.Multi, false, formatting); GeneratedRequestRunner.AddFormattedCollectionProperty(ref multi, settings, SampleValues.Items, "ids", CollectionFormat.Multi, false, formatting); Check.Require(multi.Build() == "/items?ids=1&ids=2", "The two-pass helper omits null collections and repeats Multi keys."); diff --git a/src/examples/Documentation/RuntimeHelpers/RuntimeHelpers.csproj b/src/examples/Documentation/RuntimeHelpers/RuntimeHelpers.csproj index 5b220e68f..fbf5ff9ca 100644 --- a/src/examples/Documentation/RuntimeHelpers/RuntimeHelpers.csproj +++ b/src/examples/Documentation/RuntimeHelpers/RuntimeHelpers.csproj @@ -8,6 +8,7 @@ + diff --git a/src/examples/Documentation/Serialization/Other/OtherSerializers.cs b/src/examples/Documentation/Serialization/Other/OtherSerializers.cs index 9459b11cd..bb7e52a84 100644 --- a/src/examples/Documentation/Serialization/Other/OtherSerializers.cs +++ b/src/examples/Documentation/Serialization/Other/OtherSerializers.cs @@ -50,12 +50,9 @@ private static async Task ShowNewtonsoftAsync() private static void ShowNewtonsoftSynchronous(NewtonsoftJsonContentSerializer serializer) { WirePerson? person = serializer.DeserializeFromString("""{"Id":1,"display_name":"Ada"}"""); - string? name = serializer.GetFieldNameForProperty(typeof(WirePerson).GetProperty(nameof(WirePerson.Name))!); Console.WriteLine(person?.Name); // Ada - Console.WriteLine(name); // display_name SampleCheck.Equal("Ada", person?.Name); - SampleCheck.Equal("display_name", name); } /// Checks XML configuration and an HTTP content round trip. @@ -151,10 +148,7 @@ private static async Task ShowXmlOverridesAsync() private static void ShowXmlSynchronous(XmlContentSerializer serializer) { WirePerson? person = serializer.DeserializeFromString("1Ada"); - string? name = serializer.GetFieldNameForProperty(typeof(WirePerson).GetProperty(nameof(WirePerson.Name))!); Console.WriteLine(person?.Name); // Ada - Console.WriteLine(name); // display_name SampleCheck.Equal("Ada", person?.Name); - SampleCheck.Equal("display_name", name); } } diff --git a/src/examples/Documentation/Serialization/Serialization.cs b/src/examples/Documentation/Serialization/Serialization.cs index 6206da437..ac73b83eb 100644 --- a/src/examples/Documentation/Serialization/Serialization.cs +++ b/src/examples/Documentation/Serialization/Serialization.cs @@ -53,7 +53,6 @@ internal static async Task RunAsync() await RunContextSerializerAsync(); await RunContextClientAsync(); await RunDefaultsAsync(); - VerifyFieldNames(); await RunFastPathAsync(); await RunCombinedContextsAsync(); VerifyMissingMetadata(); @@ -113,34 +112,11 @@ private static async Task RunDefaultsAsync() SampleCheck.Equal(false, ReferenceEquals(defaultOptions, separateDefaults)); SampleCheck.Equal(true, defaultOptions.PropertyNameCaseInsensitive); SampleCheck.Equal(false, defaultOptions.AllowDuplicateProperties); - SampleCheck.Equal(System.Text.Json.Serialization.JsonNumberHandling.AllowReadingFromString, defaultOptions.NumberHandling); + SampleCheck.Equal(System.Text.Json.Serialization.JsonNumberHandling.Strict, defaultOptions.NumberHandling); + SampleCheck.Equal(0, defaultOptions.Converters.Count); SampleCheck.Equal("displayName", defaultOptions.PropertyNamingPolicy!.ConvertName("DisplayName")); } - /// Checks explicit JSON property names without applying the camel-case naming policy. - private static void VerifyFieldNames() - { - JsonNamedValue model = new(); - System.Reflection.PropertyInfo explicitName = model.GetType().GetProperty(nameof(JsonNamedValue.Value))!; - System.Reflection.PropertyInfo policyOnly = typeof(Person).GetProperty(nameof(Person.Name))!; - string? name = Serializer.GetFieldNameForProperty(explicitName); - string? absent = Serializer.GetFieldNameForProperty(policyOnly); - Console.WriteLine(name); // wire-name - Console.WriteLine(absent is null); // True - SampleCheck.Equal("wire-name", name); - SampleCheck.Equal(true, absent is null); - SampleCheck.Equal("wire-name", GetCapabilityName(Serializer, explicitName)); - } - - /// Checks the reflected naming hook through the base serializer capability. - /// The content serializer capability selected by the caller. - /// The serializer whose naming contract is called. - /// The known property to inspect. - /// The explicit field name, or null. - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] - private static string? GetCapabilityName(TSerializer serializer, System.Reflection.PropertyInfo property) - where TSerializer : IHttpContentSerializer => serializer.GetFieldNameForProperty(property); - /// Checks that fast-path options work after a generated resolver is supplied. /// A task that completes after the sample assertions pass. private static async Task RunFastPathAsync() diff --git a/src/examples/Meow.Common/Meow.Common.csproj b/src/examples/Meow.Common/Meow.Common.csproj index ca2082c41..f7a31f01b 100644 --- a/src/examples/Meow.Common/Meow.Common.csproj +++ b/src/examples/Meow.Common/Meow.Common.csproj @@ -1,12 +1,13 @@ - net8.0 + net10.0 enable enable false + diff --git a/src/examples/Meow/Meow.csproj b/src/examples/Meow/Meow.csproj index bd440f3f4..8f882d95b 100644 --- a/src/examples/Meow/Meow.csproj +++ b/src/examples/Meow/Meow.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net10.0 enable enable false diff --git a/src/examples/SampleUsingLocalApi/ConsoleApplication/ConsoleSampleUsingLocalApi.csproj b/src/examples/SampleUsingLocalApi/ConsoleApplication/ConsoleSampleUsingLocalApi.csproj index 0a20d5ec7..54c909541 100644 --- a/src/examples/SampleUsingLocalApi/ConsoleApplication/ConsoleSampleUsingLocalApi.csproj +++ b/src/examples/SampleUsingLocalApi/ConsoleApplication/ConsoleSampleUsingLocalApi.csproj @@ -2,12 +2,13 @@ Exe - net8.0 + net10.0 false + diff --git a/src/examples/SampleUsingLocalApi/LibraryWithSDKandRefitService/LibraryWithSDKandRefitService.csproj b/src/examples/SampleUsingLocalApi/LibraryWithSDKandRefitService/LibraryWithSDKandRefitService.csproj index 21d74e766..fcb8a3341 100644 --- a/src/examples/SampleUsingLocalApi/LibraryWithSDKandRefitService/LibraryWithSDKandRefitService.csproj +++ b/src/examples/SampleUsingLocalApi/LibraryWithSDKandRefitService/LibraryWithSDKandRefitService.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 false diff --git a/src/examples/SampleUsingLocalApi/RestApiforTest/RestApiForTest.csproj b/src/examples/SampleUsingLocalApi/RestApiforTest/RestApiForTest.csproj index 30b51aa71..bee490f5b 100644 --- a/src/examples/SampleUsingLocalApi/RestApiforTest/RestApiForTest.csproj +++ b/src/examples/SampleUsingLocalApi/RestApiforTest/RestApiForTest.csproj @@ -1,7 +1,7 @@ - net8.0 + net10.0 InProcess false diff --git a/src/tests/Refit.Analyzers.Internals.Tests/FallbackExplanationLocateTests.cs b/src/tests/Refit.Analyzers.Internals.Tests/FallbackExplanationLocateTests.cs new file mode 100644 index 000000000..cb5cf8733 --- /dev/null +++ b/src/tests/Refit.Analyzers.Internals.Tests/FallbackExplanationLocateTests.cs @@ -0,0 +1,97 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Refit.Generator; + +namespace Refit.Analyzers.Tests; + +/// White-box tests for choosing the source location of a fallback diagnostic. +public sealed class FallbackExplanationLocateTests +{ + /// The core library file name used to resolve framework types. + private const string CoreLibraryFileName = "System.Private.CoreLib.dll"; + + /// Verifies a method-level fallback with no attribute is reported on the method. + /// A task representing the asynchronous test. + [Test] + public async Task MissingAttributeFallsBackToTheMethodLocation() + { + var (_, method) = CreateMethod(); + + var location = FallbackExplanation.Locate( + method, + InlineFallback.ForMethod(InlineFallbackReason.UnreadableHttpMethod), + null); + + await Assert.That(location).IsEqualTo(method.Locations[0]); + } + + /// Verifies an attribute with no source syntax is reported on the method. + /// A task representing the asynchronous test. + [Test] + public async Task AttributeWithoutSyntaxFallsBackToTheMethodLocation() + { + var (compilation, method) = CreateMethod(); + var metadataAttribute = compilation.GetTypeByMetadataName("System.DateTime")!.GetAttributes()[0]; + + var location = FallbackExplanation.Locate( + method, + InlineFallback.ForMethod(InlineFallbackReason.UnsupportedPathTemplate), + metadataAttribute); + + await Assert.That(location).IsEqualTo(method.Locations[0]); + } + + /// Verifies an attribute with source syntax is reported on the attribute itself. + /// A task representing the asynchronous test. + [Test] + public async Task AttributeWithSyntaxIsReportedOnTheAttribute() + { + var compilation = CSharpCompilation.Create( + "LocateTests", + [CSharpSyntaxTree.ParseText("interface I { [System.Obsolete] void M(); }")], + [MetadataReference.CreateFromFile(FindCoreLibrary())]); + var method = (IMethodSymbol)compilation.GetTypeByMetadataName("I")!.GetMembers("M")[0]; + var attribute = method.GetAttributes()[0]; + + var location = FallbackExplanation.Locate( + method, + InlineFallback.ForMethod(InlineFallbackReason.UnreadableHttpMethod), + attribute); + + var attributeSyntax = await attribute.ApplicationSyntaxReference!.GetSyntaxAsync(); + + await Assert.That(location).IsEqualTo(attributeSyntax.GetLocation()); + } + + /// Compiles an interface with one method. + /// The compilation and the method symbol. + private static (CSharpCompilation Compilation, IMethodSymbol Method) CreateMethod() + { + var compilation = CSharpCompilation.Create( + "LocateTests", + [CSharpSyntaxTree.ParseText("interface I { void M(); }")], + [MetadataReference.CreateFromFile(FindCoreLibrary())]); + var method = (IMethodSymbol)compilation.GetTypeByMetadataName("I")!.GetMembers("M")[0]; + return (compilation, method); + } + + /// Finds the core library the test runtime loaded. + /// The core library's path. + /// The runtime does not list a core library. + private static string FindCoreLibrary() + { + var trusted = (string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")!; + foreach (var path in trusted.Split(Path.PathSeparator)) + { + if (path.EndsWith(CoreLibraryFileName, StringComparison.Ordinal)) + { + return path; + } + } + + throw new InvalidOperationException("The core library was not found."); + } +} diff --git a/src/tests/Refit.Analyzers.Internals.Tests/RefitInterfaceAnalyzerTests.cs b/src/tests/Refit.Analyzers.Internals.Tests/RefitInterfaceAnalyzerTests.cs index 845aeb5f1..b03a57106 100644 --- a/src/tests/Refit.Analyzers.Internals.Tests/RefitInterfaceAnalyzerTests.cs +++ b/src/tests/Refit.Analyzers.Internals.Tests/RefitInterfaceAnalyzerTests.cs @@ -1,6 +1,9 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + namespace Refit.Analyzers.Tests; /// White-box tests for Refit interface analyzer implementation details. @@ -12,4 +15,40 @@ public sealed class RefitInterfaceAnalyzerTests [Test] public async Task GetHttpPathReturnsEmptyForMissingAttribute() => await Assert.That(RefitInterfaceAnalyzer.GetHttpPath(null)).IsEqualTo(string.Empty); + + /// Verifies HTTP path extraction reads a string first argument and ignores other attribute shapes. + /// The attributed declaration to compile. + /// The path the analyzer should read. + /// A task representing the asynchronous test. + [Test] + [Arguments("[System.Obsolete(\"/path\")] class C { }", "/path")] + [Arguments("[System.Serializable] class C { }", "")] + [Arguments("[System.AttributeUsage(System.AttributeTargets.All)] class C : System.Attribute { }", "")] + public async Task GetHttpPathReadsOnlyAStringFirstArgument(string declaration, string expected) + { + var compilation = CSharpCompilation.Create( + "PathTests", + [CSharpSyntaxTree.ParseText(declaration)], + [MetadataReference.CreateFromFile(FindCoreLibrary())]); + var symbol = compilation.GetTypeByMetadataName("C")!; + + await Assert.That(RefitInterfaceAnalyzer.GetHttpPath(symbol.GetAttributes()[0])).IsEqualTo(expected); + } + + /// Finds the core library the test runtime loaded. + /// The core library's path. + /// The runtime does not list a core library. + private static string FindCoreLibrary() + { + var trusted = (string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES")!; + foreach (var path in trusted.Split(Path.PathSeparator)) + { + if (path.EndsWith("System.Private.CoreLib.dll", StringComparison.Ordinal)) + { + return path; + } + } + + throw new InvalidOperationException("The core library was not found."); + } } diff --git a/src/tests/Refit.Analyzers.Tests/QueryDelimiterDiagnosticsTests.cs b/src/tests/Refit.Analyzers.Tests/QueryDelimiterDiagnosticsTests.cs index 3eb1bae03..fd0c12347 100644 --- a/src/tests/Refit.Analyzers.Tests/QueryDelimiterDiagnosticsTests.cs +++ b/src/tests/Refit.Analyzers.Tests/QueryDelimiterDiagnosticsTests.cs @@ -32,6 +32,7 @@ public sealed class QueryDelimiterDiagnosticsTests [Arguments("[Query(\"client_id\")][AliasAs(\"id\")] string value", false)] [Arguments("[Query(\"client_id\", Name = \"id\")] string value", false)] [Arguments("[Query(\"client_id\", Name = null)] string value", true)] + [Arguments("[Query(\"client_id\", Format = \"x\")] string value", true)] public async Task Analyze_QueryDelimiterMistakes(string parameter, bool expected, CancellationToken cancellationToken) { var diagnostics = await AnalyzerFixture.RunForBodyWithDiagnostic( diff --git a/src/tests/Refit.Analyzers.Tests/RefitInterfaceAnalyzerTests.cs b/src/tests/Refit.Analyzers.Tests/RefitInterfaceAnalyzerTests.cs index fffd0172b..0d5f15c53 100644 --- a/src/tests/Refit.Analyzers.Tests/RefitInterfaceAnalyzerTests.cs +++ b/src/tests/Refit.Analyzers.Tests/RefitInterfaceAnalyzerTests.cs @@ -561,6 +561,23 @@ public async Task ReportsUnboundRoutePlaceholderAtThePlaceholder() await Assert.That(diagnostics.Select(static diagnostic => diagnostic.Id)).DoesNotContain(GeneratedRequestBuildingFallbackDiagnosticId); } + /// Verifies a placeholder written with an escape sequence is reported on the whole path argument. + /// A task representing the asynchronous test. + [Test] + public async Task ReportsEscapedUnboundRoutePlaceholderOnThePathArgument() + { + var diagnostics = await AnalyzerFixture.RunForBody( + """ + [Get("/users/\x7bid}/posts")] + Task GetPosts(string userId); + """); + + var unbound = diagnostics.Single(static diagnostic => diagnostic.Id == UnboundRoutePlaceholderDiagnosticId); + var text = await unbound.Location.SourceTree!.GetTextAsync(); + + await Assert.That(text.ToString(unbound.Location.SourceSpan)).IsEqualTo("\"/users/\\x7bid}/posts\""); + } + /// Verifies the suggested parameter name drops the round-trip prefix and any dotted property path. /// The route template. /// The expected suggested parameter name. diff --git a/src/tests/Refit.GeneratorTests/GeneratorComponentTests.EmitterHelpers.cs b/src/tests/Refit.GeneratorTests/GeneratorComponentTests.EmitterHelpers.cs index 34c542a32..9377bad99 100644 --- a/src/tests/Refit.GeneratorTests/GeneratorComponentTests.EmitterHelpers.cs +++ b/src/tests/Refit.GeneratorTests/GeneratorComponentTests.EmitterHelpers.cs @@ -77,6 +77,34 @@ public async Task AppendEscapedCharacter_HandlesSpecialCharacters() await Assert.That(builder.ToString()).IsEqualTo("""\\\"\0\a\b\f\n\r\t\v\u0085\u2028\u2029{}x"""); } + /// Verifies characters across the whole range are either escaped or emitted unchanged. + /// A task representing the asynchronous test. + [Test] + public async Task AppendEscapedCharacter_HandlesTheWholeCharacterRange() + { + var builder = new PooledStringBuilder(); + const int lastCharacter = char.MaxValue; + for (var value = 0; value <= lastCharacter; value++) + { + LiteralEmissionHelpers.AppendEscapedCharacter(builder, (char)value, (value & 1) == 0); + } + + await Assert.That(builder.ToString().Length).IsGreaterThan(lastCharacter); + } + + /// Verifies braces are doubled in interpolated strings and left alone otherwise. + /// A task representing the asynchronous test. + [Test] + public async Task AppendEscapedCharacter_DoublesBracesWhenInterpolated() + { + var builder = new PooledStringBuilder(); + LiteralEmissionHelpers.AppendEscapedCharacter(builder, '{', true); + LiteralEmissionHelpers.AppendEscapedCharacter(builder, '}', true); + LiteralEmissionHelpers.AppendEscapedCharacter(builder, 'x', true); + + await Assert.That(builder.ToString()).IsEqualTo("{{}}x"); + } + /// Verifies unguarded indexed query emission and the shared empty parameter provider. /// A task representing the asynchronous test. [Test] diff --git a/src/tests/Refit.GeneratorTests/InternalsVisibleToGenerationTests.cs b/src/tests/Refit.GeneratorTests/InternalsVisibleToGenerationTests.cs index c49398b74..a7d488490 100644 --- a/src/tests/Refit.GeneratorTests/InternalsVisibleToGenerationTests.cs +++ b/src/tests/Refit.GeneratorTests/InternalsVisibleToGenerationTests.cs @@ -136,7 +136,6 @@ public interface IUnnamedApi // against a newline-anchored needle; otherwise the "...Generated\n" match fails on Windows runners. var generated = string.Join("\n", result.GeneratedSources.Values).Replace("\r\n", "\n"); - await Assert.That(generated).Contains("typeof(global::Refit.Implementation.Generated))"); await Assert.That(generated).Contains("namespace RefitInternalGenerated\n"); } } diff --git a/src/tests/Refit.GeneratorTests/ModuleInitializerSupportTests.cs b/src/tests/Refit.GeneratorTests/ModuleInitializerSupportTests.cs new file mode 100644 index 000000000..b10eb23f8 --- /dev/null +++ b/src/tests/Refit.GeneratorTests/ModuleInitializerSupportTests.cs @@ -0,0 +1,109 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Refit.Generator; + +namespace Refit.GeneratorTests; + +/// Verifies how the generated factory registration is hooked to assembly load. +public sealed class ModuleInitializerSupportTests +{ + /// The generated factory module's hint name. + private const string FactoryModuleHintName = "Generated.g.cs"; + + /// The generated polyfill's hint name. + private const string PolyfillHintName = "ModuleInitializerAttribute.g.cs"; + + /// The framework check the guarded registration carries. + private const string FrameworkCheck = "#if NET5_0_OR_GREATER"; + + /// Verifies a compilation that defines the attribute needs no polyfill. + /// A task that represents the asynchronous test operation. + [Test] + public async Task CompilationWithTheAttributeIsUnguarded() + { + var compilation = Fixture.CreateLibrary(CSharpSyntaxTree.ParseText("namespace Sample; public sealed class Marker { }")); + + await Assert.That(InterfaceStubGeneratorV2.DetectModuleInitializerSupport(compilation)).IsEqualTo(ModuleInitializerSupport.Unguarded); + } + + /// Verifies a compilation without the attribute asks for the polyfill. + /// A task that represents the asynchronous test operation. + [Test] + public async Task CompilationWithoutTheAttributeNeedsThePolyfill() + { + var compilation = CSharpCompilation.Create( + "NoReferences", + [CSharpSyntaxTree.ParseText("namespace Sample { public sealed class Marker { } }")]); + + await Assert.That(InterfaceStubGeneratorV2.DetectModuleInitializerSupport(compilation)).IsEqualTo(ModuleInitializerSupport.UnguardedWithPolyfill); + } + + /// Verifies a language older than C# 9 keeps the registration guarded. + /// A task that represents the asynchronous test operation. + [Test] + public async Task OldLanguageVersionStaysGuarded() + { + var tree = CSharpSyntaxTree.ParseText( + "namespace Sample { public sealed class Marker { } }", + CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp8)); + var compilation = CSharpCompilation.Create("OldLanguage", [tree]); + + await Assert.That(InterfaceStubGeneratorV2.DetectModuleInitializerSupport(compilation)).IsEqualTo(ModuleInitializerSupport.Guarded); + } + + /// Verifies the guarded registration keeps the framework check and declares no polyfill. + /// A task that represents the asynchronous test operation. + [Test] + public async Task GuardedModuleKeepsTheFrameworkCheck() + { + var sources = Emit(ModuleInitializerSupport.Guarded); + + await Assert.That(sources[FactoryModuleHintName]).Contains(FrameworkCheck); + await Assert.That(sources.ContainsKey(PolyfillHintName)).IsFalse(); + } + + /// Verifies the unguarded registration drops the framework check. + /// A task that represents the asynchronous test operation. + [Test] + public async Task UnguardedModuleDropsTheFrameworkCheck() + { + var sources = Emit(ModuleInitializerSupport.Unguarded); + + await Assert.That(sources[FactoryModuleHintName]).DoesNotContain(FrameworkCheck); + await Assert.That(sources[FactoryModuleHintName]).Contains("ModuleInitializer"); + await Assert.That(sources.ContainsKey(PolyfillHintName)).IsFalse(); + } + + /// Verifies the polyfill is declared only for targets that lack the attribute. + /// A task that represents the asynchronous test operation. + [Test] + public async Task PolyfillModuleDeclaresTheAttributeForOlderTargets() + { + var sources = Emit(ModuleInitializerSupport.UnguardedWithPolyfill); + + await Assert.That(sources[FactoryModuleHintName]).DoesNotContain(FrameworkCheck); + await Assert.That(sources[PolyfillHintName]).Contains("#if !NET5_0_OR_GREATER"); + await Assert.That(sources[PolyfillHintName]).Contains("class ModuleInitializerAttribute"); + } + + /// Emits the factory module for an empty set of interfaces. + /// The module initializer support to emit for. + /// The emitted sources by hint name. + private static Dictionary Emit(ModuleInitializerSupport support) + { + var model = new ContextGenerationModel("Consumer", "global::Preserve", "Generated", true, true, []); + Dictionary sources = []; + + SharedInfrastructureEmission.EmitGeneratedFactoryModule( + model, + "// header", + (name, text) => sources[name] = text.ToString(), + support); + + return sources; + } +} diff --git a/src/tests/Refit.GeneratorTests/NamedArgumentEdgeGenerationTests.cs b/src/tests/Refit.GeneratorTests/NamedArgumentEdgeGenerationTests.cs new file mode 100644 index 000000000..ede774e97 --- /dev/null +++ b/src/tests/Refit.GeneratorTests/NamedArgumentEdgeGenerationTests.cs @@ -0,0 +1,270 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Refit.Generator; + +namespace Refit.GeneratorTests; + +/// Verifies attribute named arguments and parameter shapes that the usual interfaces never reach. +public sealed class NamedArgumentEdgeGenerationTests +{ + /// The generated client's hint name. + private const string GeneratedClientHintName = "IGeneratedClient.g.cs"; + + /// Verifies a [Query] whose Name is explicitly null keeps the parameter's own name. + /// A task that represents the asynchronous test operation. + [Test] + public async Task QueryNameSetToNullKeepsTheParameterName() + { + var result = Fixture.RunGeneratorForBody( + """ + [Get("/a")] + Task Find([Query(Name = null)] string value); + """, + generatedRequestBuilding: true); + + await Assert.That(result.GeneratedSources[GeneratedClientHintName]).Contains("value"); + } + + /// Verifies a method with three [Url] parameters still generates and reports the problem. + /// A task that represents the asynchronous test operation. + [Test] + public async Task ThreeUrlParametersAreHandled() + { + var result = Fixture.RunGeneratorForBody( + """ + [Get("")] + Task Fetch([Url] string first, [Url] string second, [Url] string third); + """, + generatedRequestBuilding: true); + + await Assert.That(result.GeneratedSources.ContainsKey(GeneratedClientHintName)).IsTrue(); + } + + /// Verifies a query collection of an element that cannot be flattened inline still generates. + /// A task that represents the asynchronous test operation. + [Test] + public async Task QueryCollectionOfUnflattenableElementsIsHandled() + { + var result = Fixture.RunGenerator( + """ + using System.Collections.Generic; + using System.Threading.Tasks; + using Refit; + + namespace RefitGeneratorTest; + + public interface IItem + { + int Id { get; } + } + + public interface IGeneratedClient + { + [Get("/a")] + Task Find([Query(CollectionFormat.Indexed)] List items); + } + """, + generatedRequestBuilding: true); + + await Assert.That(result.GeneratedSources.ContainsKey(GeneratedClientHintName)).IsTrue(); + } + + /// Verifies a partial interface whose Refit method lives in another file still generates a client. + /// A task that represents the asynchronous test operation. + [Test] + public async Task PartialInterfaceSplitAcrossFilesIsHandled() + { + var compilation = Fixture.CreateLibrary( + CSharpSyntaxTree.ParseText( + """ + namespace RefitGeneratorTest; + + public interface IMarker + { + } + + public partial interface IGeneratedClient : IMarker + { + } + """), + CSharpSyntaxTree.ParseText( + """ + using System.Threading.Tasks; + using Refit; + + namespace RefitGeneratorTest; + + public partial interface IGeneratedClient + { + [Get("/a")] + Task Fetch(); + } + """)); + + var result = Fixture.RunGenerator(compilation, true, false, null); + + await Assert.That(result.GeneratedSources.ContainsKey(GeneratedClientHintName)).IsTrue(); + } + + /// Verifies an interface inheriting a Refit interface declared in another file still generates a client. + /// A task that represents the asynchronous test operation. + [Test] + public async Task InheritedInterfaceDeclaredInAnotherFileIsHandled() + { + var compilation = Fixture.CreateLibrary( + CSharpSyntaxTree.ParseText( + """ + using System.Threading.Tasks; + using Refit; + + namespace RefitGeneratorTest; + + public interface IBaseClient + { + [Get("/a")] + Task Fetch(); + } + """), + CSharpSyntaxTree.ParseText( + """ + namespace RefitGeneratorTest; + + public interface IDerivedClient : IBaseClient + { + } + """)); + + var result = Fixture.RunGenerator(compilation, true, false, null); + + await Assert.That(result.GeneratedSources.Count).IsGreaterThan(0); + } + + /// Verifies a compilation that does not reference Refit produces nothing and does not fail. + /// A task that represents the asynchronous test operation. + [Test] + public async Task CompilationWithoutRefitProducesNothing() + { + var withRefit = Fixture.CreateLibrary( + CSharpSyntaxTree.ParseText( + """ + using System.Threading.Tasks; + + namespace RefitGeneratorTest; + + public interface IBaseClient + { + [Custom("/a")] + Task Fetch(); + } + + public interface IDerivedClient : IBaseClient + { + } + """)); + var compilation = withRefit.RemoveReferences( + withRefit.References.Where(static reference => reference.Display?.EndsWith("Refit.dll", StringComparison.Ordinal) == true)); + + GeneratorDriver driver = CSharpGeneratorDriver.Create( + new InterfaceStubGeneratorV2().AsSourceGenerator()); + driver = driver.RunGeneratorsAndUpdateCompilation(compilation, out _, out var diagnostics); + + await Assert.That(driver.GetRunResult().GeneratedTrees.Length).IsEqualTo(0); + await Assert.That(diagnostics.Length).IsEqualTo(0); + } + + /// Verifies a relative-allowed [Url] on a string-returning method selects the relative-or-absolute kind. + /// A task that represents the asynchronous test operation. + [Test] + public async Task RelativeUrlParameterSelectsRelativeOrAbsoluteKind() + { + var result = Fixture.RunGeneratorForBody( + """ + [Get("")] + Task Fetch([Url(AllowRelative = true)] string url); + """, + generatedRequestBuilding: true); + + await Assert.That(result.GeneratedSources[GeneratedClientHintName]).Contains("global::System.UriKind.RelativeOrAbsolute"); + } + + /// Verifies a relative-allowed [Url] on an observable-returning method selects the relative-or-absolute kind. + /// A task that represents the asynchronous test operation. + [Test] + public async Task RelativeUrlParameterOnObservableSelectsRelativeOrAbsoluteKind() + { + var result = Fixture.RunGeneratorForBody( + """ + [Get("")] + System.IObservable Fetch([Url(AllowRelative = true)] string url); + """, + generatedRequestBuilding: true); + + await Assert.That(result.GeneratedSources[GeneratedClientHintName]).Contains("global::System.UriKind.RelativeOrAbsolute"); + } + + /// Verifies an indexed query collection with an explicit delimiter flattens its elements inline. + /// A task that represents the asynchronous test operation. + [Test] + public async Task IndexedQueryCollectionWithExplicitDelimiterIsGenerated() + { + var result = Fixture.RunGenerator( + """ + using System.Collections.Generic; + using System.Threading.Tasks; + using Refit; + + namespace RefitGeneratorTest; + + public sealed class Item + { + public int Id { get; set; } + } + + public interface IGeneratedClient + { + [Get("/a")] + Task Find([Query("::", CollectionFormat.Indexed)] List items); + } + """, + generatedRequestBuilding: true); + + await Assert.That(result.GeneratedSources[GeneratedClientHintName]).Contains("::"); + } + + /// Verifies an attributed member that is not a Refit method is ignored alongside a Refit method. + /// A task that represents the asynchronous test operation. + [Test] + public async Task AttributedNonRefitMethodIsIgnored() + { + var result = Fixture.RunGeneratorForBody( + """ + [Get("/a")] + Task Fetch(); + + [System.Obsolete] + void Other(); + """, + generatedRequestBuilding: true); + + await Assert.That(result.GeneratedSources.ContainsKey(GeneratedClientHintName)).IsTrue(); + } + + /// Verifies a method returning an array is classified without a named return type. + /// A task that represents the asynchronous test operation. + [Test] + public async Task ArrayReturnTypeIsHandled() + { + var result = Fixture.RunGeneratorForBody( + """ + [Get("/a")] + string[] Fetch(); + """, + generatedRequestBuilding: true); + + await Assert.That(result.GeneratedSources.ContainsKey(GeneratedClientHintName)).IsTrue(); + } +} diff --git a/src/tests/Refit.GeneratorTests/QueryNestingDelimiterTests.cs b/src/tests/Refit.GeneratorTests/QueryNestingDelimiterTests.cs new file mode 100644 index 000000000..2baf11c11 --- /dev/null +++ b/src/tests/Refit.GeneratorTests/QueryNestingDelimiterTests.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using Refit.Generator; + +namespace Refit.GeneratorTests; + +/// Verifies the delimiter placed between nested query keys. +public sealed class QueryNestingDelimiterTests +{ + /// Verifies an explicit delimiter is used. + /// A task that represents the asynchronous test operation. + [Test] + public async Task ExplicitDelimiterIsUsed() + { + var data = new RequestBodyParsing.QueryFormData("::", null, null, null, false, false, null); + + await Assert.That(QueryParameterParsing.ResolveNestingDelimiter(data)).IsEqualTo("::"); + } + + /// Verifies the default delimiter is used when none is declared. + /// A task that represents the asynchronous test operation. + [Test] + public async Task MissingDelimiterUsesTheDefault() + { + var data = new RequestBodyParsing.QueryFormData(null, null, null, null, false, false, null); + + await Assert.That(QueryParameterParsing.ResolveNestingDelimiter(data)).IsEqualTo(QueryParameterParsing.DefaultNestingDelimiter); + } +} diff --git a/src/tests/Refit.GeneratorTests/QueryRequestBuildingLiveTests.Helpers.cs b/src/tests/Refit.GeneratorTests/QueryRequestBuildingLiveTests.Helpers.cs index 7ddf69104..434f80574 100644 --- a/src/tests/Refit.GeneratorTests/QueryRequestBuildingLiveTests.Helpers.cs +++ b/src/tests/Refit.GeneratorTests/QueryRequestBuildingLiveTests.Helpers.cs @@ -17,7 +17,7 @@ private sealed class UpperCaseUrlParameterFormatter : DefaultUrlParameterFormatt /// public override string? Format( object? value, - System.Reflection.ICustomAttributeProvider attributeProvider, + IParameterAttributeProvider attributeProvider, Type type) => base.Format(value, attributeProvider, type)?.ToUpperInvariant(); } diff --git a/src/tests/Refit.GeneratorTests/RequestGenerationCoverageTests.FormBody.cs b/src/tests/Refit.GeneratorTests/RequestGenerationCoverageTests.FormBody.cs index 2dcadea5b..3b6a5c29c 100644 --- a/src/tests/Refit.GeneratorTests/RequestGenerationCoverageTests.FormBody.cs +++ b/src/tests/Refit.GeneratorTests/RequestGenerationCoverageTests.FormBody.cs @@ -72,6 +72,156 @@ await Assert.That(generated).Contains( await Assert.That(generated).DoesNotContain("body.@Ignored"); } + /// Verifies the form-field descriptor carries the JSON, Newtonsoft and XML names beside the explicit name. + /// A task representing the asynchronous test. + [Test] + public async Task UrlEncodedFormBodyDescriptorCarriesSerializerNames() + { + const string Source = + """ + using System.Collections.Generic; + using System.Text.Json.Serialization; + using System.Threading.Tasks; + using System.Xml.Serialization; + using Refit; + + namespace Newtonsoft.Json + { + [System.AttributeUsage(System.AttributeTargets.Property)] + public sealed class JsonPropertyAttribute : System.Attribute + { + public JsonPropertyAttribute() { } + + public JsonPropertyAttribute(string propertyName) => PropertyName = propertyName; + + public string PropertyName { get; set; } + } + } + + namespace RefitGeneratorTest + { + public class NamedForm + { + [JsonPropertyName("json_roles")] + [Newtonsoft.Json.JsonProperty("newtonsoft_roles")] + [XmlElement("xml_roles")] + public List Roles { get; set; } + + [AliasAs("alias")] + [JsonPropertyName("json_name")] + public string Name { get; set; } + + [XmlAttribute] + public List Unnamed { get; set; } + } + + public interface IGeneratedClient + { + [Post("/named")] + Task Submit([Body(BodySerializationMethod.UrlEncoded)] NamedForm form); + } + } + """; + + var result = Fixture.RunGenerator(Source, generatedRequestBuilding: true); + var generated = result.GeneratedSources[GeneratedClientHintName]; + + await Assert.That(result.CompilesWithoutErrors).IsTrue(); + await Assert.That(generated).Contains("new global::Refit.FormFieldNames(null, \"json_roles\", \"newtonsoft_roles\", \"xml_roles\")"); + await Assert.That(generated).Contains("new global::Refit.FormFieldNames(\"alias\", \"json_name\", null, null)"); + await Assert.That(generated).Contains("new global::Refit.FormFieldNames(null, null, null, \"\")"); + } + + /// Verifies the descriptor reads serializer names given as named attribute arguments. + /// A task representing the asynchronous test. + [Test] + public async Task UrlEncodedFormBodyDescriptorReadsNamedAttributeArguments() + { + const string Source = + """ + using System.Collections.Generic; + using System.Threading.Tasks; + using System.Xml.Serialization; + using Refit; + + namespace Newtonsoft.Json + { + [System.AttributeUsage(System.AttributeTargets.Property)] + public sealed class JsonPropertyAttribute : System.Attribute + { + public string PropertyName { get; set; } + } + } + + namespace RefitGeneratorTest + { + public class NamedArgumentForm + { + [Newtonsoft.Json.JsonProperty(PropertyName = "newtonsoft_named")] + [XmlElement(ElementName = "xml_named")] + public List Both { get; set; } + + [XmlAttribute(AttributeName = "attribute_named")] + public List OnlyAttribute { get; set; } + + [XmlElement(Namespace = "urn:other")] + public List OtherNamedArgument { get; set; } + } + + public interface IGeneratedClient + { + [Post("/named")] + Task Submit([Body(BodySerializationMethod.UrlEncoded)] NamedArgumentForm form); + } + } + """; + + var result = Fixture.RunGenerator(Source, generatedRequestBuilding: true); + var generated = result.GeneratedSources[GeneratedClientHintName]; + + await Assert.That(result.CompilesWithoutErrors).IsTrue(); + await Assert.That(generated).Contains("new global::Refit.FormFieldNames(null, null, \"newtonsoft_named\", \"xml_named\")"); + await Assert.That(generated).Contains("new global::Refit.FormFieldNames(null, null, null, \"attribute_named\")"); + await Assert.That(generated).Contains("new global::Refit.FormFieldNames(null, null, null, \"\")"); + } + + /// Verifies an unrolled scalar form body asks the serializer-aware key helper and guards on the name style. + /// A task representing the asynchronous test. + [Test] + public async Task UnrolledFormBodyUsesSerializerAwareKeyAndStyleGuard() + { + const string Source = + """ + using System.Text.Json.Serialization; + using System.Threading.Tasks; + using Refit; + + namespace RefitGeneratorTest; + + public sealed class ScalarForm + { + [JsonPropertyName("json_name")] + public string Name { get; set; } + + public string Plain { get; set; } + } + + public interface IGeneratedClient + { + [Post("/scalar")] + Task Submit([Body(BodySerializationMethod.UrlEncoded)] ScalarForm form); + } + """; + + var result = Fixture.RunGenerator(Source, generatedRequestBuilding: true); + var generated = result.GeneratedSources[GeneratedClientHintName]; + + await Assert.That(result.CompilesWithoutErrors).IsTrue(); + await Assert.That(generated).Contains("ContentSerializer is global::Refit.IContentSerializerNameStyle"); + await Assert.That(generated).Contains("GeneratedRequestRunner.BuildFormKey("); + await Assert.That(generated).Contains("GeneratedRequestRunner.BuildQueryKey("); + } + /// Verifies an unrolled scalar form body emits the empty-value branch for a nullable /// [Query(SerializeNull = true)] field, alongside an unconditionally added value-type field. /// A task representing the asynchronous test. diff --git a/src/tests/Refit.GeneratorTests/RequestGenerationCoverageTests.Query.cs b/src/tests/Refit.GeneratorTests/RequestGenerationCoverageTests.Query.cs index 85ef1c0ac..6819b82f9 100644 --- a/src/tests/Refit.GeneratorTests/RequestGenerationCoverageTests.Query.cs +++ b/src/tests/Refit.GeneratorTests/RequestGenerationCoverageTests.Query.cs @@ -100,7 +100,7 @@ public void Flatten(IDictionary value, string keyPrefix, ref Gen { foreach (var entry in value) { - builder.Add(keyPrefix + entry.Key, settings.UrlParameterFormatter.Format(entry.Value, typeof(object), typeof(object)), false); + builder.Add(keyPrefix + entry.Key, settings.UrlParameterFormatter.Format(entry.Value, GeneratedParameterAttributeProvider.Empty, typeof(object)), false); } } } diff --git a/src/tests/Refit.GeneratorTests/RequestParameterBodyModelEqualityTests.cs b/src/tests/Refit.GeneratorTests/RequestParameterBodyModelEqualityTests.cs new file mode 100644 index 000000000..ef666780e --- /dev/null +++ b/src/tests/Refit.GeneratorTests/RequestParameterBodyModelEqualityTests.cs @@ -0,0 +1,81 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using Refit.Generator; + +namespace Refit.GeneratorTests; + +/// Verifies the body model reports a difference in any single member, which incremental caching relies on. +public sealed class RequestParameterBodyModelEqualityTests +{ + /// The model every case is compared against. + private static readonly RequestParameterBodyModel Baseline = new( + "Serialize", + BodyBufferMode.Settings, + null, + "gzip", + "fast", + new MultipartPartModel(default, "field", "file", false), + "Item", + false); + + /// Verifies two models with the same members are equal and hash alike. + /// A task that represents the asynchronous test operation. + [Test] + public async Task EqualModelsAreEqualAndHashAlike() + { + var copy = Baseline with { }; + + await Assert.That(copy.Equals(Baseline)).IsTrue(); + await Assert.That(copy.GetHashCode()).IsEqualTo(Baseline.GetHashCode()); + } + + /// Verifies a change to the serialization method makes the models differ. + /// A task that represents the asynchronous test operation. + [Test] + public async Task SerializationMethodDifferenceIsDetected() => + await Assert.That(Baseline.Equals(Baseline with { BodySerializationMethod = "Other" })).IsFalse(); + + /// Verifies a change to the buffer mode makes the models differ. + /// A task that represents the asynchronous test operation. + [Test] + public async Task BufferModeDifferenceIsDetected() => + await Assert.That(Baseline.Equals(Baseline with { BodyBufferMode = BodyBufferMode.None })).IsFalse(); + + /// Verifies a change to the form fields makes the models differ. + /// A task that represents the asynchronous test operation. + [Test] + public async Task FormFieldsDifferenceIsDetected() => + await Assert.That(Baseline.Equals(Baseline with { FormFields = [] })).IsFalse(); + + /// Verifies a change to the compression makes the models differ. + /// A task that represents the asynchronous test operation. + [Test] + public async Task CompressionDifferenceIsDetected() => + await Assert.That(Baseline.Equals(Baseline with { Compression = "br" })).IsFalse(); + + /// Verifies a change to the compression level makes the models differ. + /// A task that represents the asynchronous test operation. + [Test] + public async Task CompressionLevelDifferenceIsDetected() => + await Assert.That(Baseline.Equals(Baseline with { CompressionLevel = "best" })).IsFalse(); + + /// Verifies a change to the multipart part makes the models differ. + /// A task that represents the asynchronous test operation. + [Test] + public async Task MultipartPartDifferenceIsDetected() => + await Assert.That(Baseline.Equals(Baseline with { MultipartPart = null })).IsFalse(); + + /// Verifies a change to the JSON Lines element type makes the models differ. + /// A task that represents the asynchronous test operation. + [Test] + public async Task JsonLinesElementTypeDifferenceIsDetected() => + await Assert.That(Baseline.Equals(Baseline with { JsonLinesElementType = "Other" })).IsFalse(); + + /// Verifies a change to the async JSON Lines flag makes the models differ. + /// A task that represents the asynchronous test operation. + [Test] + public async Task AsyncJsonLinesDifferenceIsDetected() => + await Assert.That(Baseline.Equals(Baseline with { IsAsyncJsonLines = true })).IsFalse(); +} diff --git a/src/tests/Refit.GeneratorTests/ReturnTypeInfoClassificationTests.cs b/src/tests/Refit.GeneratorTests/ReturnTypeInfoClassificationTests.cs new file mode 100644 index 000000000..bf437269f --- /dev/null +++ b/src/tests/Refit.GeneratorTests/ReturnTypeInfoClassificationTests.cs @@ -0,0 +1,70 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Refit.Generator; + +namespace Refit.GeneratorTests; + +/// Verifies every return type shape the generator classifies. +public sealed class ReturnTypeInfoClassificationTests +{ + /// The source declaring one method per return type shape. + private const string Source = + """ + using System; + using System.Collections.Generic; + using System.Net.Http; + using System.Threading.Tasks; + + namespace Shapes + { + public class PagedEnumerable + { + } + + public interface IShapes + { + Task AsyncVoid(); + Task AsyncResult(); + Task RequestMessage(); + ValueTask ValueResult(); + IAsyncEnumerable AsyncEnumerable(); + IObservable Observable(); + PagedEnumerable LookAlikePaged(); + Refit.PagedEnumerable Paged(); + void SyncVoid(); + int Plain(); + int[] Array(); + Func ThreeArguments(); + } + } + """; + + /// Verifies each declared shape maps to the expected classification. + /// The method whose return type is classified. + /// The expected classification. + /// A task that represents the asynchronous test operation. + [Test] + [Arguments("AsyncVoid", "AsyncVoid")] + [Arguments("AsyncResult", "AsyncResult")] + [Arguments("RequestMessage", "RequestMessage")] + [Arguments("ValueResult", "AsyncResult")] + [Arguments("AsyncEnumerable", "AsyncEnumerable")] + [Arguments("Observable", "Observable")] + [Arguments("LookAlikePaged", "Return")] + [Arguments("Paged", "Paged")] + [Arguments("SyncVoid", "SyncVoid")] + [Arguments("Plain", "Return")] + [Arguments("Array", "Return")] + [Arguments("ThreeArguments", "Return")] + public async Task ReturnTypeShapesAreClassified(string methodName, string expected) + { + var compilation = Fixture.CreateLibrary(CSharpSyntaxTree.ParseText(Source)); + var method = (IMethodSymbol)compilation.GetTypeByMetadataName("Shapes.IShapes")!.GetMembers(methodName)[0]; + + await Assert.That(InterfaceMemberParsing.GetReturnTypeInfo(method)).IsEqualTo(Enum.Parse(expected)); + } +} diff --git a/src/tests/Refit.GeneratorTests/_snapshots/GeneratedTest.ShouldEmitAllFiles#Generated.g.verified.cs b/src/tests/Refit.GeneratorTests/_snapshots/GeneratedTest.ShouldEmitAllFiles#Generated.g.verified.cs index b6c982762..3316ac806 100644 --- a/src/tests/Refit.GeneratorTests/_snapshots/GeneratedTest.ShouldEmitAllFiles#Generated.g.verified.cs +++ b/src/tests/Refit.GeneratorTests/_snapshots/GeneratedTest.ShouldEmitAllFiles#Generated.g.verified.cs @@ -14,16 +14,13 @@ namespace Refit.Implementation [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] internal static partial class GeneratedCompilation { -#if NET5_0_OR_GREATER + /// Registers generated Refit factories when the assembly is loaded. [global::System.Diagnostics.CodeAnalysis.SuppressMessage( "Usage", "CA2255:The ModuleInitializer attribute should not be used in libraries", Justification = "ModuleInitializer is used intentionally so generated Refit factories are registered when the assembly loads.")] [System.Runtime.CompilerServices.ModuleInitializer] - [System.Diagnostics.CodeAnalysis.DynamicDependency( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, - typeof(global::Refit.Implementation.GeneratedCompilation))] internal static void Initialize() { global::Refit.RestService.RegisterGeneratedFactory( @@ -33,6 +30,6 @@ internal static void Initialize() static (client, settings) => new global::Refit.Implementation.GeneratedCompilation.RefitGeneratorTestIGeneratedClient(client, settings)); } -#endif + } } diff --git a/src/tests/Refit.GeneratorTests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#Generated.g.verified.cs b/src/tests/Refit.GeneratorTests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#Generated.g.verified.cs index 5d9889c4a..cf7bc3780 100644 --- a/src/tests/Refit.GeneratorTests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#Generated.g.verified.cs +++ b/src/tests/Refit.GeneratorTests/_snapshots/InterfaceStubGeneratorTests.FindInterfacesSmokeTest#Generated.g.verified.cs @@ -14,16 +14,13 @@ namespace Refit.Implementation [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] internal static partial class GeneratedCompilation { -#if NET5_0_OR_GREATER + /// Registers generated Refit factories when the assembly is loaded. [global::System.Diagnostics.CodeAnalysis.SuppressMessage( "Usage", "CA2255:The ModuleInitializer attribute should not be used in libraries", Justification = "ModuleInitializer is used intentionally so generated Refit factories are registered when the assembly loads.")] [System.Runtime.CompilerServices.ModuleInitializer] - [System.Diagnostics.CodeAnalysis.DynamicDependency( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, - typeof(global::Refit.Implementation.GeneratedCompilation))] internal static void Initialize() { global::Refit.RestService.RegisterGeneratedFactory( @@ -45,6 +42,6 @@ internal static void Initialize() static (client, settings) => new global::Refit.Implementation.GeneratedCompilation.RefitTestsTestNestedINestedGitHubApi(client, settings)); } -#endif + } } diff --git a/src/tests/Refit.GeneratorTests/_snapshots/InterfaceStubGeneratorTests.GenerateInterfaceStubsWithoutNamespaceSmokeTest#Generated.g.verified.cs b/src/tests/Refit.GeneratorTests/_snapshots/InterfaceStubGeneratorTests.GenerateInterfaceStubsWithoutNamespaceSmokeTest#Generated.g.verified.cs index ae895ecfd..c70d7a7a4 100644 --- a/src/tests/Refit.GeneratorTests/_snapshots/InterfaceStubGeneratorTests.GenerateInterfaceStubsWithoutNamespaceSmokeTest#Generated.g.verified.cs +++ b/src/tests/Refit.GeneratorTests/_snapshots/InterfaceStubGeneratorTests.GenerateInterfaceStubsWithoutNamespaceSmokeTest#Generated.g.verified.cs @@ -14,16 +14,13 @@ namespace Refit.Implementation [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] internal static partial class GeneratedCompilation { -#if NET5_0_OR_GREATER + /// Registers generated Refit factories when the assembly is loaded. [global::System.Diagnostics.CodeAnalysis.SuppressMessage( "Usage", "CA2255:The ModuleInitializer attribute should not be used in libraries", Justification = "ModuleInitializer is used intentionally so generated Refit factories are registered when the assembly loads.")] [System.Runtime.CompilerServices.ModuleInitializer] - [System.Diagnostics.CodeAnalysis.DynamicDependency( - System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All, - typeof(global::Refit.Implementation.GeneratedCompilation))] internal static void Initialize() { global::Refit.RestService.RegisterGeneratedFactory( @@ -33,6 +30,6 @@ internal static void Initialize() static (client, settings) => new global::Refit.Implementation.GeneratedCompilation.IServiceWithoutNamespace(client, settings)); } -#endif + } } diff --git a/src/tests/Refit.GeneratorTests/_snapshots/PagedReturnSnapshotTests.CursorFromBody#IGeneratedClient.g.verified.cs b/src/tests/Refit.GeneratorTests/_snapshots/PagedReturnSnapshotTests.CursorFromBody#IGeneratedClient.g.verified.cs index 2c694124a..51546e081 100644 --- a/src/tests/Refit.GeneratorTests/_snapshots/PagedReturnSnapshotTests.CursorFromBody#IGeneratedClient.g.verified.cs +++ b/src/tests/Refit.GeneratorTests/_snapshots/PagedReturnSnapshotTests.CursorFromBody#IGeneratedClient.g.verified.cs @@ -1,4 +1,4 @@ -//HintName: IGeneratedClient.g.cs +//HintName: IGeneratedClient.g.cs // #nullable enable annotations @@ -46,7 +46,7 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli _settings = settings; } /// Cached attribute provider for the generated BuildRefitListPageRequest method's token parameter. - private static readonly global::System.Reflection.ICustomAttributeProvider ______tokenAttributeProvider = new global::Refit.GeneratedParameterAttributeProvider(new global::System.Collections.Generic.Dictionary() {{ typeof(global::Refit.PageTokenAttribute), new object[] { new global::Refit.PageTokenAttribute()} }, { typeof(global::Refit.AliasAsAttribute), new object[] { new global::Refit.AliasAsAttribute("continuation-token")} }}); + private static readonly global::Refit.IParameterAttributeProvider ______tokenAttributeProvider = new global::Refit.GeneratedParameterAttributeProvider(new global::System.Collections.Generic.Dictionary() {{ typeof(global::Refit.PageTokenAttribute), new object[] { new global::Refit.PageTokenAttribute()} }, { typeof(global::Refit.AliasAsAttribute), new object[] { new global::Refit.AliasAsAttribute("continuation-token")} }}); /// public global::System.Net.Http.HttpRequestMessage BuildRefitListPageRequest(string @bucket, string? @prefix, string? @token) diff --git a/src/tests/Refit.GeneratorTests/_snapshots/PagedReturnSnapshotTests.OffsetFromTotal#IGeneratedClient.g.verified.cs b/src/tests/Refit.GeneratorTests/_snapshots/PagedReturnSnapshotTests.OffsetFromTotal#IGeneratedClient.g.verified.cs index 163044a75..9e24e7420 100644 --- a/src/tests/Refit.GeneratorTests/_snapshots/PagedReturnSnapshotTests.OffsetFromTotal#IGeneratedClient.g.verified.cs +++ b/src/tests/Refit.GeneratorTests/_snapshots/PagedReturnSnapshotTests.OffsetFromTotal#IGeneratedClient.g.verified.cs @@ -1,4 +1,4 @@ -//HintName: IGeneratedClient.g.cs +//HintName: IGeneratedClient.g.cs // #nullable enable annotations @@ -46,7 +46,7 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli _settings = settings; } /// Cached attribute provider for the generated BuildRefitSearchPageRequest method's startAt parameter. - private static readonly global::System.Reflection.ICustomAttributeProvider ______startAtAttributeProvider = new global::Refit.GeneratedParameterAttributeProvider(new global::System.Collections.Generic.Dictionary() {{ typeof(global::Refit.PageTokenAttribute), new object[] { new global::Refit.PageTokenAttribute()} }, { typeof(global::Refit.AliasAsAttribute), new object[] { new global::Refit.AliasAsAttribute("startAt")} }}); + private static readonly global::Refit.IParameterAttributeProvider ______startAtAttributeProvider = new global::Refit.GeneratedParameterAttributeProvider(new global::System.Collections.Generic.Dictionary() {{ typeof(global::Refit.PageTokenAttribute), new object[] { new global::Refit.PageTokenAttribute()} }, { typeof(global::Refit.AliasAsAttribute), new object[] { new global::Refit.AliasAsAttribute("startAt")} }}); /// public global::System.Net.Http.HttpRequestMessage BuildRefitSearchPageRequest(string @jql, int @startAt) diff --git a/src/tests/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameterInQueryWithAttribute#IGeneratedClient.g.verified.cs b/src/tests/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameterInQueryWithAttribute#IGeneratedClient.g.verified.cs index 0406b4efc..2e95dedc8 100644 --- a/src/tests/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameterInQueryWithAttribute#IGeneratedClient.g.verified.cs +++ b/src/tests/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameterInQueryWithAttribute#IGeneratedClient.g.verified.cs @@ -1,4 +1,4 @@ -//HintName: IGeneratedClient.g.cs +//HintName: IGeneratedClient.g.cs // #nullable enable annotations @@ -46,7 +46,7 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli _settings = settings; } /// Cached attribute provider for the generated Find method's q parameter. - private static readonly global::System.Reflection.ICustomAttributeProvider ______qAttributeProvider = new global::Refit.GeneratedSingleTypeParameterAttributeProvider(typeof(global::Refit.QueryAttribute), new object[] { new global::Refit.QueryAttribute() }); + private static readonly global::Refit.IParameterAttributeProvider ______qAttributeProvider = new global::Refit.GeneratedSingleTypeParameterAttributeProvider(typeof(global::Refit.QueryAttribute), new object[] { new global::Refit.QueryAttribute() }); /// public global::System.Threading.Tasks.Task Find(string? @q) diff --git a/src/tests/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameterWithAttribute#IGeneratedClient.g.verified.cs b/src/tests/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameterWithAttribute#IGeneratedClient.g.verified.cs index bd8228f95..d9ed36899 100644 --- a/src/tests/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameterWithAttribute#IGeneratedClient.g.verified.cs +++ b/src/tests/Refit.GeneratorTests/_snapshots/ParameterTests.ValueTypeRouteParameterWithAttribute#IGeneratedClient.g.verified.cs @@ -1,4 +1,4 @@ -//HintName: IGeneratedClient.g.cs +//HintName: IGeneratedClient.g.cs // #nullable enable annotations @@ -46,7 +46,7 @@ public RefitGeneratorTestIGeneratedClient(global::System.Net.Http.HttpClient cli _settings = settings; } /// Cached attribute provider for the generated Get method's id parameter. - private static readonly global::System.Reflection.ICustomAttributeProvider ______idAttributeProvider = new global::Refit.GeneratedSingleTypeParameterAttributeProvider(typeof(global::Refit.QueryAttribute), new object[] { new global::Refit.QueryAttribute(){ Format = "00" } }); + private static readonly global::Refit.IParameterAttributeProvider ______idAttributeProvider = new global::Refit.GeneratedSingleTypeParameterAttributeProvider(typeof(global::Refit.QueryAttribute), new object[] { new global::Refit.QueryAttribute(){ Format = "00" } }); /// public global::System.Threading.Tasks.Task Get(int? @id) diff --git a/src/tests/Refit.Newtonsoft.Json.Tests/NewtonsoftFormFieldNameTests.cs b/src/tests/Refit.Newtonsoft.Json.Tests/NewtonsoftFormFieldNameTests.cs new file mode 100644 index 000000000..4157bcd72 --- /dev/null +++ b/src/tests/Refit.Newtonsoft.Json.Tests/NewtonsoftFormFieldNameTests.cs @@ -0,0 +1,56 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace Refit.Tests; + +/// Verifies generated form-field descriptors resolve names the way the Newtonsoft serializer does. +public sealed class NewtonsoftFormFieldNameTests +{ + /// Verifies the Newtonsoft serializer reports the Newtonsoft name style. + /// A task representing the asynchronous test. + [Test] + public async Task SerializerReportsNewtonsoftNameStyle() => + await Assert.That(new NewtonsoftJsonContentSerializer().NameStyle).IsEqualTo(ContentSerializerNameStyle.Newtonsoft); + + /// Verifies the descriptor path picks the Newtonsoft name and agrees with the reflection path. + /// A task representing the asynchronous test. + [Test] + public async Task DescriptorPathUsesNewtonsoftNameAndMatchesReflection() + { + ReflectionSupport.EnsureRegistered(); + var settings = new RefitSettings(new NewtonsoftJsonContentSerializer()); + var body = new NamedBody { Renamed = "r", Unnamed = "u", Aliased = "a", }; + var fields = new[] + { + new FormField(static b => b.Renamed, nameof(NamedBody.Renamed), new(null, "json", "newtonsoft_name", null), null, null, null, false), + new FormField(static b => b.Unnamed, nameof(NamedBody.Unnamed), new(null, "json_unnamed", null, null), null, null, null, false), + new FormField(static b => b.Aliased, nameof(NamedBody.Aliased), new("alias", "json_aliased", "newtonsoft_aliased", null), null, null, null, false), + }; + + var descriptor = await GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, fields).ReadAsStringAsync(); + var reflection = await GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body).ReadAsStringAsync(); + + await Assert.That(descriptor).IsEqualTo("newtonsoft_name=r&Unnamed=u&alias=a"); + await Assert.That(descriptor).IsEqualTo(reflection); + } + + /// Form body whose properties carry Newtonsoft naming attributes. + private sealed class NamedBody + { + /// Gets or sets the property renamed through Newtonsoft. + [JsonProperty("newtonsoft_name")] + public string? Renamed { get; set; } + + /// Gets or sets the property with no Newtonsoft name. + public string? Unnamed { get; set; } + + /// Gets or sets the property whose alias wins over the Newtonsoft name. + [AliasAs("alias")] + [JsonProperty("newtonsoft_aliased")] + public string? Aliased { get; set; } + } +} diff --git a/src/tests/Refit.Newtonsoft.Json.Tests/NewtonsoftJsonSecurityTests.cs b/src/tests/Refit.Newtonsoft.Json.Tests/NewtonsoftJsonSecurityTests.cs index a09f59ca6..55acd18d3 100644 --- a/src/tests/Refit.Newtonsoft.Json.Tests/NewtonsoftJsonSecurityTests.cs +++ b/src/tests/Refit.Newtonsoft.Json.Tests/NewtonsoftJsonSecurityTests.cs @@ -42,6 +42,50 @@ public async Task GlobalTypeNameHandlingIsForcedOffWhenNoExplicitSettings() } } + /// Verifies the serializer uses fresh settings when no global settings factory is configured. + /// A task representing the asynchronous test. + [Test] + public async Task MissingGlobalSettingsFactoryFallsBackToNewSettings() + { + var previous = JsonConvert.DefaultSettings; + JsonConvert.DefaultSettings = null; + + try + { + var serializer = new NewtonsoftJsonContentSerializer(); + + var json = await serializer.ToHttpContent(new SampleModel { Name = "unset" }).ReadAsStringAsync(); + + await Assert.That(json).Contains("unset"); + } + finally + { + JsonConvert.DefaultSettings = previous; + } + } + + /// Verifies a global settings factory that returns falls back to fresh settings. + /// A task representing the asynchronous test. + [Test] + public async Task GlobalSettingsFactoryReturningNullFallsBackToNewSettings() + { + var previous = JsonConvert.DefaultSettings; + JsonConvert.DefaultSettings = static () => null!; + + try + { + var serializer = new NewtonsoftJsonContentSerializer(); + + var json = await serializer.ToHttpContent(new SampleModel { Name = "fallback" }).ReadAsStringAsync(); + + await Assert.That(json).Contains("fallback"); + } + finally + { + JsonConvert.DefaultSettings = previous; + } + } + /// Verifies a caller that explicitly opts into TypeNameHandling is honored. /// A task representing the asynchronous test. [Test] diff --git a/src/tests/Refit.Newtonsoft.Json.Tests/SerializedContentNewtonsoftTests.cs b/src/tests/Refit.Newtonsoft.Json.Tests/SerializedContentNewtonsoftTests.cs index 5fc3fad6a..5d5eb07ed 100644 --- a/src/tests/Refit.Newtonsoft.Json.Tests/SerializedContentNewtonsoftTests.cs +++ b/src/tests/Refit.Newtonsoft.Json.Tests/SerializedContentNewtonsoftTests.cs @@ -144,46 +144,34 @@ public async Task StreamDeserialization_UsingNewtonsoftJsonContentSerializer_Ret await Assert.That(result).IsNull(); } - /// Verifies that the Newtonsoft content serializer returns the JsonProperty name for a property. + /// Verifies that Refit resolves the JsonProperty name for a property with the Newtonsoft serializer. /// A task that represents the asynchronous test operation. [Test] - public async Task NewtonsoftJsonContentSerializer_GetFieldNameForProperty_ReturnsJsonPropertyName() + public async Task SerializerFieldNames_Newtonsoft_ReturnsJsonPropertyName() { var serializer = new NewtonsoftJsonContentSerializer(); var property = typeof(NewtonsoftFieldNameModel).GetProperty( nameof(NewtonsoftFieldNameModel.Name)); - var fieldName = serializer.GetFieldNameForProperty(property!); + var fieldName = SerializerFieldNames.Resolve(serializer, property!); await Assert.That(fieldName).IsEqualTo("json_name"); } - /// Verifies that the Newtonsoft content serializer returns null when no JsonProperty attribute exists. + /// Verifies that Refit resolves no name when no JsonProperty attribute exists. /// A task that represents the asynchronous test operation. [Test] - public async Task NewtonsoftJsonContentSerializer_GetFieldNameForProperty_ReturnsNullWithoutJsonPropertyAttribute() + public async Task SerializerFieldNames_Newtonsoft_ReturnsNullWithoutJsonPropertyAttribute() { var serializer = new NewtonsoftJsonContentSerializer(); var property = typeof(NewtonsoftFieldNameModel).GetProperty( nameof(NewtonsoftFieldNameModel.Unaliased)); - var fieldName = serializer.GetFieldNameForProperty(property!); + var fieldName = SerializerFieldNames.Resolve(serializer, property!); await Assert.That(fieldName).IsNull(); } - /// Verifies that the Newtonsoft content serializer throws when the property argument is null. - /// A task that represents the asynchronous test operation. - [Test] - public async Task NewtonsoftJsonContentSerializer_GetFieldNameForProperty_ThrowsForNullProperty() - { - var serializer = new NewtonsoftJsonContentSerializer(); - - var exception = await Assert.That(() => serializer.GetFieldNameForProperty(null!)).ThrowsExactly(); - - await Assert.That(exception!.ParamName).IsEqualTo("propertyInfo"); - } - /// Verifies quoted charsets are unwrapped before Newtonsoft deserialization resolves the encoding. /// A task that represents the asynchronous test operation. [Test] diff --git a/src/tests/Refit.Testing.Tests/ReflectionRegistration.cs b/src/tests/Refit.Testing.Tests/ReflectionRegistration.cs new file mode 100644 index 000000000..d4b7cd87f --- /dev/null +++ b/src/tests/Refit.Testing.Tests/ReflectionRegistration.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Runtime.CompilerServices; + +namespace Refit.Testing.Tests; + +/// Registers reflection-based JSON for the tests that stub typed replies without a source-generated context. +internal static class ReflectionRegistration +{ + /// Registers the reflection support once, before any test runs. + [ModuleInitializer] + internal static void Register() => ReflectionSupport.EnsureRegistered(); +} diff --git a/src/tests/Refit.Testing.Tests/RetryDelayProvidersTests.cs b/src/tests/Refit.Testing.Tests/RetryDelayProvidersTests.cs index e9c5f19e9..fc0aae6a2 100644 --- a/src/tests/Refit.Testing.Tests/RetryDelayProvidersTests.cs +++ b/src/tests/Refit.Testing.Tests/RetryDelayProvidersTests.cs @@ -83,6 +83,7 @@ public async Task Azure_PrefersMilliseconds(CancellationToken cancellationToken) [Arguments(RetryHeaderFormat.Iso8601Date, "1970-01-01T00:00:00.000Z", 0L)] [Arguments(RetryHeaderFormat.Iso8601Date, "1970-01-01T00:00:20", null)] [Arguments(RetryHeaderFormat.Iso8601Date, "tomorrow", null)] + [Arguments(RetryHeaderFormat.Iso8601Date, "", null)] public async Task ReadHeader_ValidatesEncoding(RetryHeaderFormat format, string value, long? milliseconds, CancellationToken cancellationToken) { using var response = new HttpResponseMessage(); diff --git a/src/tests/Refit.Tests/ApiExceptionTests.Content.cs b/src/tests/Refit.Tests/ApiExceptionTests.Content.cs index 68ecd10ca..606321ed3 100644 --- a/src/tests/Refit.Tests/ApiExceptionTests.Content.cs +++ b/src/tests/Refit.Tests/ApiExceptionTests.Content.cs @@ -243,9 +243,5 @@ private sealed class AsyncOnlySerializer : IHttpContentSerializer /// public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => _inner.FromHttpContentAsync(content, cancellationToken); - - /// - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) => - _inner.GetFieldNameForProperty(propertyInfo); } } diff --git a/src/tests/Refit.Tests/ApiExceptionTests.cs b/src/tests/Refit.Tests/ApiExceptionTests.cs index c7bcca7f0..463d1bdd1 100644 --- a/src/tests/Refit.Tests/ApiExceptionTests.cs +++ b/src/tests/Refit.Tests/ApiExceptionTests.cs @@ -487,10 +487,6 @@ private sealed class AsyncYieldingSerializer : IHttpContentSerializer await Task.Yield(); return await _inner.FromHttpContentAsync(content, cancellationToken).ConfigureAwait(false); } - - /// - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) => - _inner.GetFieldNameForProperty(propertyInfo); } /// Response model used by content deserialization tests. diff --git a/src/tests/Refit.Tests/ApiResponseEnsureSuccessTests.cs b/src/tests/Refit.Tests/ApiResponseEnsureSuccessTests.cs index e8b2a3852..a7d061d73 100644 --- a/src/tests/Refit.Tests/ApiResponseEnsureSuccessTests.cs +++ b/src/tests/Refit.Tests/ApiResponseEnsureSuccessTests.cs @@ -30,6 +30,24 @@ await Assert .ThrowsExactly(); } + /// Verifies the interface-typed guards return the same response when it succeeded. + /// A task representing the asynchronous test. + [Test] + public async Task InterfaceTypedGuardsReturnSuccessfulResponse() + { + using var request = new HttpRequestMessage(HttpMethod.Get, ExampleUri); + using var okResponse = new HttpResponseMessage(HttpStatusCode.OK) { RequestMessage = request }; + using var success = new ApiResponse(okResponse, "body", new()); + + IApiResponse generic = success; + IApiResponse nonGeneric = success; + + await Assert.That(await generic.EnsureSuccessStatusCodeAsync()).IsSameReferenceAs(success); + await Assert.That(await generic.EnsureSuccessfulAsync()).IsSameReferenceAs(success); + await Assert.That(await nonGeneric.EnsureSuccessStatusCodeAsync()).IsSameReferenceAs(success); + await Assert.That(await nonGeneric.EnsureSuccessfulAsync()).IsSameReferenceAs(success); + } + /// Verifies the generic EnsureSuccessfulAsync returns the response on success and throws the error on failure. /// A task representing the asynchronous test. [Test] diff --git a/src/tests/Refit.Tests/AsyncEnumerableObservableTests.cs b/src/tests/Refit.Tests/AsyncEnumerableObservableTests.cs index 8e9ba549a..2dcfbdf75 100644 --- a/src/tests/Refit.Tests/AsyncEnumerableObservableTests.cs +++ b/src/tests/Refit.Tests/AsyncEnumerableObservableTests.cs @@ -130,6 +130,20 @@ public async Task Subscribe_ObserverThrows_StillDisposesTheSource() await Assert.That(observer.Completed).IsFalse(); } + /// Verifies an observer that throws still disposes a source whose disposal finishes asynchronously. + /// A task that represents the asynchronous operation. + [Test] + public async Task Subscribe_ObserverThrowsWithAsynchronousDisposal_StillDisposesTheSource() + { + var sourceDisposed = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); + var observer = new RecordingObserver { OnNextStep = static _ => throw new InvalidOperationException("observer failed") }; + + using var subscription = new AsyncEnumerableObservable(DisposeSlowly(sourceDisposed)).Subscribe(observer); + + await Assert.That(sourceDisposed.Task).CompletesWithin(AwaitTimeout); + await Assert.That(observer.Completed).IsFalse(); + } + /// Verifies a source whose disposal fails after a subscription was disposed delivers nothing further. /// A task that represents the asynchronous operation. [Test] diff --git a/src/tests/Refit.Tests/BracketUrlParameterFormatter.cs b/src/tests/Refit.Tests/BracketUrlParameterFormatter.cs index 55a72d96c..806efd46b 100644 --- a/src/tests/Refit.Tests/BracketUrlParameterFormatter.cs +++ b/src/tests/Refit.Tests/BracketUrlParameterFormatter.cs @@ -1,9 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. - -using System.Reflection; - namespace Refit.Tests; /// A non-default URL parameter formatter that wraps each formatted value in brackets, used to prove the @@ -11,6 +8,6 @@ namespace Refit.Tests; public sealed class BracketUrlParameterFormatter : IUrlParameterFormatter { /// - public string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type) => + public string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type) => value is null ? null : $"[{value}]"; } diff --git a/src/tests/Refit.Tests/CachedRequestBuilderTests.cs b/src/tests/Refit.Tests/CachedRequestBuilderTests.cs index 8f940bfeb..b69891721 100644 --- a/src/tests/Refit.Tests/CachedRequestBuilderTests.cs +++ b/src/tests/Refit.Tests/CachedRequestBuilderTests.cs @@ -120,7 +120,7 @@ private sealed class CountingRequestBuilder : IRequestBuilder } /// Content serializer test double used only to satisfy construction. - private sealed class NullContentSerializer : IHttpContentSerializer + private sealed class NullContentSerializer : IHttpContentSerializer, IReflectionFieldNameProvider { /// public HttpContent ToHttpContent(T item) => new ByteArrayContent([]); diff --git a/src/tests/Refit.Tests/CamelCaseStringEnumConverterTests.cs b/src/tests/Refit.Tests/CamelCaseStringEnumConverterTests.cs deleted file mode 100644 index 89606e852..000000000 --- a/src/tests/Refit.Tests/CamelCaseStringEnumConverterTests.cs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. -// ReactiveUI and Contributors licenses this file to you under the MIT license. -// See the LICENSE file in the project root for full license information. - -namespace Refit.Tests; - -/// Pins the serialized-name maps the camelCase enum converter builds from an enum's fields, so the build path -/// stays behavior-preserving under allocation refactoring. -public sealed class CamelCaseStringEnumConverterTests -{ - /// The expected names-to-values entry count: two entries each for DateDescending and Name - /// (camelCase plus declared name) and one for the already-lowercase plain. - private const int ExpectedNameEntryCount = 5; - - /// The camelCase preferred name of . - private const string DateDescendingCamelCase = "dateDescending"; - - /// An enum whose members exercise the camelCase preferred name plus the declared-name fallback. - private enum SortOrder - { - /// A multi-word member whose camelCase name ("dateDescending") differs from its declared name. - DateDescending = 0, - - /// A single-word member whose camelCase name ("name") differs from its declared name. - Name = 1, - - /// An already-lowercase member whose camelCase name equals its declared name, contributing one entry. - plain = 2, - } - - /// Verifies the names-to-values map carries both the camelCase preferred name and the declared name for a - /// member whose two names differ, and a single entry for an already-lowercase member. - /// A task that represents the asynchronous operation. - [Test] - public async Task NamesToValuesMapCarriesCamelCaseAndDeclaredNames() - { - var map = CamelCaseStringEnumConverter.EnumConverter.BuildNameMaps().NamesToValues; - - await Assert.That(map[DateDescendingCamelCase]).IsEqualTo(SortOrder.DateDescending); - await Assert.That(map["DateDescending"]).IsEqualTo(SortOrder.DateDescending); - await Assert.That(map["name"]).IsEqualTo(SortOrder.Name); - await Assert.That(map["Name"]).IsEqualTo(SortOrder.Name); - await Assert.That(map["plain"]).IsEqualTo(SortOrder.plain); - - // "plain" is already lowercase, so its camelCase and declared names coincide and it contributes one entry only. - await Assert.That(map.Count).IsEqualTo(ExpectedNameEntryCount); - } - - /// Verifies the ordinal-ignore-case map resolves a name regardless of case, while the ordinal map is - /// case-sensitive, matching the two lookups the converter performs. - /// A task that represents the asynchronous operation. - [Test] - public async Task NamesToValuesMapsHonorComparerCaseSensitivity() - { - var maps = CamelCaseStringEnumConverter.EnumConverter.BuildNameMaps(); - - await Assert.That(maps.NamesToValues.ContainsKey("DATEDESCENDING")).IsFalse(); - await Assert.That(maps.NamesToValuesIgnoreCase["DATEDESCENDING"]).IsEqualTo(SortOrder.DateDescending); - } - - /// Verifies a constructed converter builds its ordinal names-to-values map from the enum's fields, so the - /// entry count it exposes matches the map produced by . - /// A task that represents the asynchronous operation. - [Test] - public async Task ConstructedConverterMapEntryCountMatchesBuiltNameMap() - { - var converter = new CamelCaseStringEnumConverter.EnumConverter(); - - await Assert.That(converter.MapEntryCount).IsEqualTo(ExpectedNameEntryCount); - } - - /// Verifies the values-to-names map yields each value's camelCase preferred name. - /// A task that represents the asynchronous operation. - [Test] - public async Task ValuesToNamesMapYieldsPreferredCamelCaseName() - { - var map = CamelCaseStringEnumConverter.EnumConverter.BuildNameMaps().ValuesToNames; - - await Assert.That(map[SortOrder.DateDescending]).IsEqualTo(DateDescendingCamelCase); - await Assert.That(map[SortOrder.Name]).IsEqualTo("name"); - await Assert.That(map[SortOrder.plain]).IsEqualTo("plain"); - } - - /// Verifies camelCase conversion lowercases only the first character and returns non-uppercase-leading and - /// empty inputs unchanged. - /// A task that represents the asynchronous operation. - [Test] - public async Task ToCamelCaseLowercasesOnlyTheFirstCharacter() - { - await Assert.That(CamelCaseStringEnumConverter.ToCamelCase("DateDescending")).IsEqualTo(DateDescendingCamelCase); - await Assert.That(CamelCaseStringEnumConverter.ToCamelCase("A")).IsEqualTo("a"); - await Assert.That(CamelCaseStringEnumConverter.ToCamelCase("ABC")).IsEqualTo("aBC"); - await Assert.That(CamelCaseStringEnumConverter.ToCamelCase("already")).IsEqualTo("already"); - await Assert.That(CamelCaseStringEnumConverter.ToCamelCase("_leading")).IsEqualTo("_leading"); - await Assert.That(CamelCaseStringEnumConverter.ToCamelCase(string.Empty)).IsEqualTo(string.Empty); - } -} diff --git a/src/tests/Refit.Tests/DefaultResolverAssignmentTests.cs b/src/tests/Refit.Tests/DefaultResolverAssignmentTests.cs new file mode 100644 index 000000000..c8a02fcbe --- /dev/null +++ b/src/tests/Refit.Tests/DefaultResolverAssignmentTests.cs @@ -0,0 +1,44 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Text.Json; + +namespace Refit.Tests; + +/// Verifies the default reflection resolver is assigned once and never to options that cannot take it. +public sealed class DefaultResolverAssignmentTests +{ + /// Verifies assigning twice keeps the first resolver. + /// A task that represents the asynchronous test operation. + [Test] + public async Task SecondAssignmentKeepsTheFirstResolver() + { + ReflectionSupport.EnsureRegistered(); + var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions(); + var serializer = new SystemTextJsonContentSerializer(options); + + serializer.AssignDefaultResolver(); + var first = options.TypeInfoResolver; + serializer.AssignDefaultResolver(); + + await Assert.That(first).IsNotNull(); + await Assert.That(options.TypeInfoResolver).IsSameReferenceAs(first); + } + + /// Verifies options that already carry a resolver, even read-only ones, are left alone. + /// A task that represents the asynchronous test operation. + [Test] + public async Task ReadOnlyOptionsWithAResolverAreNotAssigned() + { + var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions(); + options.TypeInfoResolver = new System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver(); + var resolver = options.TypeInfoResolver; + options.MakeReadOnly(); + var serializer = new SystemTextJsonContentSerializer(options); + + serializer.AssignDefaultResolver(); + + await Assert.That(options.TypeInfoResolver).IsSameReferenceAs(resolver); + } +} diff --git a/src/tests/Refit.Tests/DefaultUrlParameterFormatterTests.ValueFormatting.cs b/src/tests/Refit.Tests/DefaultUrlParameterFormatterTests.ValueFormatting.cs index 3c8e61f02..dfb9902be 100644 --- a/src/tests/Refit.Tests/DefaultUrlParameterFormatterTests.ValueFormatting.cs +++ b/src/tests/Refit.Tests/DefaultUrlParameterFormatterTests.ValueFormatting.cs @@ -16,9 +16,9 @@ public async Task FormatReturnsStringVerbatimAndRendersFormattableInvariantly() const int sample = 1234; var formatter = new DefaultUrlParameterFormatter(); - await Assert.That(formatter.Format("widgets and gadgets", typeof(string), typeof(string))) + await Assert.That(formatter.Format("widgets and gadgets", GeneratedParameterAttributeProvider.Empty, typeof(string))) .IsEqualTo("widgets and gadgets"); - await Assert.That(formatter.Format(sample, typeof(int), typeof(int))) + await Assert.That(formatter.Format(sample, GeneratedParameterAttributeProvider.Empty, typeof(int))) .IsEqualTo("1234"); } @@ -30,9 +30,9 @@ public async Task FormatFallsBackToToStringForNonFormattableValues() { var formatter = new DefaultUrlParameterFormatter(); - await Assert.That(formatter.Format(new NonFormattableValue(), typeof(NonFormattableValue), typeof(NonFormattableValue))) + await Assert.That(formatter.Format(new NonFormattableValue(), GeneratedParameterAttributeProvider.Empty, typeof(NonFormattableValue))) .IsEqualTo("custom-text"); - await Assert.That(formatter.Format(new NullToStringValue(), typeof(NullToStringValue), typeof(NullToStringValue))) + await Assert.That(formatter.Format(new NullToStringValue(), GeneratedParameterAttributeProvider.Empty, typeof(NullToStringValue))) .IsEqualTo(string.Empty); } diff --git a/src/tests/Refit.Tests/DefaultUrlParameterFormatterTests.cs b/src/tests/Refit.Tests/DefaultUrlParameterFormatterTests.cs index a03c988c7..0e26b8fba 100644 --- a/src/tests/Refit.Tests/DefaultUrlParameterFormatterTests.cs +++ b/src/tests/Refit.Tests/DefaultUrlParameterFormatterTests.cs @@ -38,7 +38,7 @@ public async Task NullParameterValue_ReturnsNull() var output = urlParameterFormatter.Format( parameters.DateTime, - parameters.GetType().GetProperty(nameof(parameters.DateTime))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTime))!), parameters.GetType()); await Assert.That(output).IsNull(); @@ -55,7 +55,7 @@ public async Task NoFormatters_UseDefaultFormat() var output = urlParameterFormatter.Format( parameters.DateTime, - parameters.GetType().GetProperty(nameof(parameters.DateTime))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTime))!), parameters.GetType()); await Assert.That(output).IsEqualTo("08/21/2023 00:00:00"); @@ -72,7 +72,7 @@ public async Task QueryAttributeFormatOnly_UseQueryAttributeFormat() var output = urlParameterFormatter.Format( parameters.DateTimeWithAttributeFormatYear, - parameters.GetType().GetProperty(nameof(parameters.DateTimeWithAttributeFormatYear))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTimeWithAttributeFormatYear))!), parameters.GetType()); await Assert.That(output).IsEqualTo("2023"); @@ -90,7 +90,7 @@ public async Task QueryAttributeAndGeneralFormat_UseQueryAttributeFormat() var output = urlParameterFormatter.Format( parameters.DateTimeWithAttributeFormatYear, - parameters.GetType().GetProperty(nameof(parameters.DateTimeWithAttributeFormatYear))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTimeWithAttributeFormatYear))!), parameters.GetType()); await Assert.That(output).IsEqualTo("2023"); @@ -108,7 +108,7 @@ public async Task QueryAttributeAndSpecificFormat_UseQueryAttributeFormat() var output = urlParameterFormatter.Format( parameters.DateTimeWithAttributeFormatYear, - parameters.GetType().GetProperty(nameof(parameters.DateTimeWithAttributeFormatYear))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTimeWithAttributeFormatYear))!), parameters.GetType()); await Assert.That(output).IsEqualTo("2023"); @@ -127,7 +127,7 @@ public async Task AllFormats_UseQueryAttributeFormat() var output = urlParameterFormatter.Format( parameters.DateTimeWithAttributeFormatYear, - parameters.GetType().GetProperty(nameof(parameters.DateTimeWithAttributeFormatYear))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTimeWithAttributeFormatYear))!), parameters.GetType()); await Assert.That(output).IsEqualTo("2023"); @@ -145,7 +145,7 @@ public async Task GeneralFormatOnly_UseGeneralFormat() var output = urlParameterFormatter.Format( parameters.DateTime, - parameters.GetType().GetProperty(nameof(parameters.DateTime))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTime))!), parameters.GetType()); await Assert.That(output).IsEqualTo("2023"); @@ -163,7 +163,7 @@ public async Task SpecificFormatOnly_UseSpecificFormat() var output = urlParameterFormatter.Format( parameters.DateTime, - parameters.GetType().GetProperty(nameof(parameters.DateTime))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTime))!), parameters.GetType()); await Assert.That(output).IsEqualTo("2023"); @@ -182,7 +182,7 @@ public async Task GeneralAndSpecificFormats_UseSpecificFormat() var output = urlParameterFormatter.Format( parameters.DateTime, - parameters.GetType().GetProperty(nameof(parameters.DateTime))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.DateTime))!), parameters.GetType()); await Assert.That(output).IsEqualTo("2023"); @@ -306,7 +306,7 @@ public async Task CombinedFlagsEnumValue_DoesNotThrow() var output = urlParameterFormatter.Format( parameters.Flags, - parameters.GetType().GetProperty(nameof(parameters.Flags))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.Flags))!), parameters.GetType()); await Assert.That(output).IsEqualTo("First, Second"); @@ -323,7 +323,7 @@ public async Task UndefinedEnumValue_DoesNotThrow() var output = urlParameterFormatter.Format( parameters.Flags, - parameters.GetType().GetProperty(nameof(parameters.Flags))!, + new CachedAttributeProvider(parameters.GetType().GetProperty(nameof(parameters.Flags))!), parameters.GetType()); await Assert.That(output).IsEqualTo("-1"); diff --git a/src/tests/Refit.Tests/DictionaryObjectQueryConverter.cs b/src/tests/Refit.Tests/DictionaryObjectQueryConverter.cs index 8f3bece25..4d5141266 100644 --- a/src/tests/Refit.Tests/DictionaryObjectQueryConverter.cs +++ b/src/tests/Refit.Tests/DictionaryObjectQueryConverter.cs @@ -22,7 +22,7 @@ public void Flatten( continue; } - var formatted = settings.UrlParameterFormatter.Format(entry.Value, typeof(object), typeof(object)); + var formatted = settings.UrlParameterFormatter.Format(entry.Value, GeneratedParameterAttributeProvider.Empty, typeof(object)); builder.Add(keyPrefix + entry.Key, formatted, false); } } diff --git a/src/tests/Refit.Tests/EnumHelpersTests.cs b/src/tests/Refit.Tests/EnumHelpersTests.cs index deb0b88d7..47eb8a2ac 100644 --- a/src/tests/Refit.Tests/EnumHelpersTests.cs +++ b/src/tests/Refit.Tests/EnumHelpersTests.cs @@ -128,6 +128,12 @@ public async Task GetEnumMemberValueHandlesAttributeAndFallbackCases() await Assert.That(EnumHelpers.GetEnumMemberValue(typeof(MemberEnum), MemberEnum.Custom)).IsEqualTo("custom-value"); } + /// Verifies the lookup yields no value when no resolver is registered. + /// A task representing the asynchronous test. + [Test] + public async Task GetEnumMemberValueReturnsNullWithoutARegisteredResolver() => + await Assert.That(EnumHelpers.GetEnumMemberValue(null, typeof(MemberEnum), MemberEnum.Custom)).IsNull(); + /// Verifies numeric enum helpers preserve every supported signed and unsigned backing type. /// A task representing the asynchronous test. [Test] diff --git a/src/tests/Refit.Tests/GeneratedJsonTypeInfoParameterTests.cs b/src/tests/Refit.Tests/GeneratedJsonTypeInfoParameterTests.cs index 76165b39e..1adc93cfc 100644 --- a/src/tests/Refit.Tests/GeneratedJsonTypeInfoParameterTests.cs +++ b/src/tests/Refit.Tests/GeneratedJsonTypeInfoParameterTests.cs @@ -1,7 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; using System.Text.Json.Serialization.Metadata; namespace Refit.Tests; @@ -235,9 +234,6 @@ private sealed class PlainContentSerializer : IHttpContentSerializer /// public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => Task.FromResult(default); - - /// - public string? GetFieldNameForProperty(PropertyInfo propertyInfo) => null; } /// An observer that completes a task with the first value it receives. diff --git a/src/tests/Refit.Tests/GeneratedRequestRunnerJsonTypeInfoTests.cs b/src/tests/Refit.Tests/GeneratedRequestRunnerJsonTypeInfoTests.cs index 024df9717..003a83c07 100644 --- a/src/tests/Refit.Tests/GeneratedRequestRunnerJsonTypeInfoTests.cs +++ b/src/tests/Refit.Tests/GeneratedRequestRunnerJsonTypeInfoTests.cs @@ -191,8 +191,5 @@ private sealed class NonMetadataContentSerializer : IHttpContentSerializer /// public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => Task.FromResult(default); - - /// - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) => null; } } diff --git a/src/tests/Refit.Tests/GeneratedRequestRunnerTests.Collections.cs b/src/tests/Refit.Tests/GeneratedRequestRunnerTests.Collections.cs index 24b7f803e..1fc9f8799 100644 --- a/src/tests/Refit.Tests/GeneratedRequestRunnerTests.Collections.cs +++ b/src/tests/Refit.Tests/GeneratedRequestRunnerTests.Collections.cs @@ -198,7 +198,7 @@ private static string AddFormattedCollectionProperty(IEnumerable? values, Collec CollectionPropertyKey, collectionFormat, false, - (typeof(string), typeof(string), typeof(string))); + (typeof(string), GeneratedParameterAttributeProvider.Empty, typeof(string))); return builder.Build(); } } diff --git a/src/tests/Refit.Tests/GeneratedRequestRunnerTests.RoundTripEscaping.cs b/src/tests/Refit.Tests/GeneratedRequestRunnerTests.RoundTripEscaping.cs index b3f676e2d..32947ac5f 100644 --- a/src/tests/Refit.Tests/GeneratedRequestRunnerTests.RoundTripEscaping.cs +++ b/src/tests/Refit.Tests/GeneratedRequestRunnerTests.RoundTripEscaping.cs @@ -18,7 +18,7 @@ public async Task RoundTripEscapePathEscapesEachSectionUnderDefaultFormatter() var result = GeneratedRequestRunner.RoundTripEscapePath( "aa a/bb-b/c%d/e", settings, - typeof(string), + GeneratedParameterAttributeProvider.Empty, typeof(string)); await Assert.That(result).IsEqualTo("aa%20a/bb-b/c%25d/e"); @@ -35,7 +35,7 @@ public async Task RoundTripEscapePathRendersNullValueAsEmptyUnderDefaultFormatte var result = GeneratedRequestRunner.RoundTripEscapePath( null, settings, - typeof(string), + GeneratedParameterAttributeProvider.Empty, typeof(string)); await Assert.That(result).IsEqualTo(string.Empty); diff --git a/src/tests/Refit.Tests/GeneratedRequestRunnerTests.cs b/src/tests/Refit.Tests/GeneratedRequestRunnerTests.cs index 40a2a46dd..6ad3c0494 100644 --- a/src/tests/Refit.Tests/GeneratedRequestRunnerTests.cs +++ b/src/tests/Refit.Tests/GeneratedRequestRunnerTests.cs @@ -13,6 +13,9 @@ public partial class GeneratedRequestRunnerTests /// An arbitrary form-field name, alongside "Note" and "Roles"; unrelated to any type in scope. private const string SkipFieldName = "Skip"; + /// The Newtonsoft field name used by the serializer-name descriptor tests. + private const string NewtonsoftFieldName = "newtonsoft"; + /// Relative request path shared by the generated-runner fixtures. private const string RelativeResourcePath = "/resource"; @@ -249,7 +252,7 @@ public async Task CreateUrlEncodedBodyContentWithFieldsUsesDescriptorsForSystemT var body = new DeclaredFormBody { Name = "Ada" }; var fields = new[] { - new FormField(static _ => "from-getter", "Name", "renamed", null, null, null, false), + new FormField(static _ => "from-getter", "Name", new("renamed", null, null, null), null, null, null, false), }; var result = GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, fields); @@ -257,6 +260,66 @@ public async Task CreateUrlEncodedBodyContentWithFieldsUsesDescriptorsForSystemT await Assert.That(await result.ReadAsStringAsync()).IsEqualTo("renamed=from-getter"); } + /// Verifies the descriptor overload picks the serializer-specific name for the XML serializer. + /// A task representing the asynchronous test. + [Test] + public async Task CreateUrlEncodedBodyContentWithFieldsUsesXmlNameForXmlSerializer() + { + var settings = new RefitSettings(new XmlContentSerializer()); + var body = new DeclaredFormBody { Name = "Ada" }; + var fields = new[] + { + new FormField(static b => b.Name, "Name", new(null, "json", NewtonsoftFieldName, "xml"), null, null, null, false), + }; + + var result = GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, fields); + + await Assert.That(await result.ReadAsStringAsync()).IsEqualTo("xml=Ada"); + } + + /// Verifies the descriptor overload picks the JSON name for System.Text.Json and lets an explicit name win. + /// A task representing the asynchronous test. + [Test] + public async Task CreateUrlEncodedBodyContentWithFieldsPrefersExplicitNameOverSerializerNames() + { + var settings = new RefitSettings(new SystemTextJsonContentSerializer()); + var body = new DeclaredFormBody { Name = "Ada" }; + var jsonFields = new[] + { + new FormField(static b => b.Name, "Name", new(null, "json", NewtonsoftFieldName, "xml"), null, null, null, false), + }; + var explicitFields = new[] + { + new FormField(static b => b.Name, "Name", new("alias", "json", NewtonsoftFieldName, "xml"), null, null, null, false), + }; + + var json = await GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, jsonFields).ReadAsStringAsync(); + var explicitName = await GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, explicitFields).ReadAsStringAsync(); + + await Assert.That(json).IsEqualTo("json=Ada"); + await Assert.That(explicitName).IsEqualTo("alias=Ada"); + } + + /// Verifies the descriptor path and the reflection path agree on XML serializer names. + /// A task representing the asynchronous test. + [Test] + public async Task XmlDescriptorAndReflectionFormPathsProduceIdenticalOutput() + { + var settings = new RefitSettings(new XmlContentSerializer()); + var body = new XmlNamedFormBody { Element = "e", Attribute = "a", Unnamed = "u", }; + var fields = new[] + { + new FormField(static b => b.Element, "Element", new(null, null, null, "el"), null, null, null, false), + new FormField(static b => b.Attribute, nameof(XmlNamedFormBody.Attribute), new(null, null, null, "at"), null, null, null, false), + new FormField(static b => b.Unnamed, "Unnamed", new(null, null, null, string.Empty), null, null, null, false), + }; + + var descriptor = await GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, fields).ReadAsStringAsync(); + var reflection = await new FormUrlEncodedContent(new FormValueMultimap(body, settings)).ReadAsStringAsync(); + + await Assert.That(descriptor).IsEqualTo(reflection); + } + /// Verifies the descriptor overload falls back to reflection for a custom content serializer. /// A task representing the asynchronous test. [Test] @@ -266,7 +329,7 @@ public async Task CreateUrlEncodedBodyContentWithFieldsFallsBackForCustomSeriali var body = new DeclaredFormBody { Name = "Ada" }; var fields = new[] { - new FormField(static _ => "from-getter", "Name", "renamed", null, null, null, false), + new FormField(static _ => "from-getter", "Name", new("renamed", null, null, null), null, null, null, false), }; var result = GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, fields); @@ -308,9 +371,9 @@ public async Task CreateUrlEncodedBodyContentWithFieldsSerializesNullsAndCollect var body = new DeclaredFormBody(); var fields = new[] { - new FormField(static _ => null, "Note", "note", null, null, null, serializeNull: true), - new FormField(static _ => new List { "a", "b" }, "Roles", "roles", null, null, CollectionFormat.Multi, false), - new FormField(static _ => null, SkipFieldName, "skip", null, null, null, serializeNull: false), + new FormField(static _ => null, "Note", new("note", null, null, null), null, null, null, serializeNull: true), + new FormField(static _ => new List { "a", "b" }, "Roles", new("roles", null, null, null), null, null, CollectionFormat.Multi, false), + new FormField(static _ => null, SkipFieldName, new("skip", null, null, null), null, null, null, serializeNull: false), }; var result = GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, fields); @@ -327,7 +390,7 @@ public async Task CreateUrlEncodedBodyContentWithFieldsAppliesPrefixSegment() var body = new DeclaredFormBody { Name = "v" }; var fields = new[] { - new FormField(static b => b.Name, "Name", null, "pre-", null, null, false), + new FormField(static b => b.Name, "Name", default, "pre-", null, null, false), }; var result = GeneratedRequestRunner.CreateUrlEncodedBodyContent(settings, body, fields); @@ -343,10 +406,10 @@ public async Task DescriptorAndReflectionFormPathsProduceIdenticalOutput() var body = new ParityFormBody { WebPropertyId = "UA-1", Plain = "p", Note = null, Roles = ["x", "y"], }; var fields = new[] { - new FormField(static b => b.WebPropertyId, "WebPropertyId", "tid", null, null, null, false), - new FormField(static b => b.Plain, "Plain", null, null, null, null, false), - new FormField(static b => b.Note, "Note", null, null, null, null, serializeNull: true), - new FormField(static b => b.Roles, "Roles", null, null, null, CollectionFormat.Multi, false), + new FormField(static b => b.WebPropertyId, "WebPropertyId", new("tid", null, null, null), null, null, null, false), + new FormField(static b => b.Plain, "Plain", default, null, null, null, false), + new FormField(static b => b.Note, "Note", default, null, null, null, serializeNull: true), + new FormField(static b => b.Roles, "Roles", default, null, null, CollectionFormat.Multi, false), }; // SystemTextJson takes the generated descriptor path; the recording serializer forces the reflection path. @@ -454,7 +517,7 @@ public async Task RoundTripEscapePathSubstitutesEmptyForNullFormattedSection() var result = GeneratedRequestRunner.RoundTripEscapePath( "a/b", settings, - typeof(string), + GeneratedParameterAttributeProvider.Empty, typeof(string)); await Assert.That(result).IsEqualTo("/"); @@ -519,7 +582,7 @@ private async Task SendAndAttachRequestAsync( } /// Records serializer usage and returns configured test values. - private sealed class RecordingContentSerializer : IHttpContentSerializer + private sealed class RecordingContentSerializer : IHttpContentSerializer, IReflectionFieldNameProvider { /// Gets the number of serialization calls. public int SerializeCallCount { get; private set; } @@ -645,7 +708,7 @@ private sealed class FormattableReference : IFormattable private sealed class NullUrlParameterFormatter : IUrlParameterFormatter { /// - public string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type) => null; + public string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type) => null; } /// Declared form model used to verify generated URL-encoded bodies use compile-time metadata. @@ -662,6 +725,22 @@ private sealed class DerivedFormBody : DeclaredFormBody public string? Hidden { get; set; } } + /// Form model whose properties carry XML naming attributes. + private sealed class XmlNamedFormBody + { + /// Gets or sets the element-named property. + [System.Xml.Serialization.XmlElement("el")] + public string? Element { get; set; } + + /// Gets or sets the attribute-named property. + [System.Xml.Serialization.XmlAttribute("at")] + public string? Attribute { get; set; } + + /// Gets or sets the property with an unnamed element attribute. + [System.Xml.Serialization.XmlElement] + public string? Unnamed { get; set; } + } + /// Form model used to compare the descriptor and reflection serialization paths. private sealed class ParityFormBody { diff --git a/src/tests/Refit.Tests/HttpClientFactoryExtensionsTests.ServiceCollection.cs b/src/tests/Refit.Tests/HttpClientFactoryExtensionsTests.ServiceCollection.cs index e0072c955..aff665ec9 100644 --- a/src/tests/Refit.Tests/HttpClientFactoryExtensionsTests.ServiceCollection.cs +++ b/src/tests/Refit.Tests/HttpClientFactoryExtensionsTests.ServiceCollection.cs @@ -353,15 +353,15 @@ await Assert.That( await Assert.That(serviceProvider.GetRequiredKeyedService(TypeNoneKey)).IsNotNull(); } - /// Verifies the generic (IServiceCollection, RefitSettings) overload still exists for binary compatibility. + /// Verifies the generic (IServiceCollection, RefitSettings) overload exists in the reflection package. /// A task that represents the asynchronous operation. [Test] - public async Task AddRefitClient_ServiceCollectionGenericSettingsOverload_RemainsBinaryCompatible() + public async Task AddRefitClient_ServiceCollectionGenericSettingsOverload_ExistsInReflectionPackage() { - var method = typeof(HttpClientFactoryExtensions) + var method = typeof(HttpClientFactoryReflectionExtensions) .GetMethods(BindingFlags.Public | BindingFlags.Static) .SingleOrDefault(static method => - method.Name == nameof(HttpClientFactoryExtensions.AddRefitClient) + method.Name == nameof(HttpClientFactoryReflectionExtensions.AddRefitClient) && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 1 && method.GetParameters() is @@ -375,15 +375,15 @@ public async Task AddRefitClient_ServiceCollectionGenericSettingsOverload_Remain await Assert.That(method).IsNotNull(); } - /// Verifies the (IServiceCollection, Type, RefitSettings) overload still exists for binary compatibility. + /// Verifies the (IServiceCollection, Type, RefitSettings) overload exists in the reflection package. /// A task that represents the asynchronous operation. [Test] - public async Task AddRefitClient_ServiceCollectionTypeSettingsOverload_RemainsBinaryCompatible() + public async Task AddRefitClient_ServiceCollectionTypeSettingsOverload_ExistsInReflectionPackage() { - var method = typeof(HttpClientFactoryExtensions) + var method = typeof(HttpClientFactoryReflectionExtensions) .GetMethods(BindingFlags.Public | BindingFlags.Static) .SingleOrDefault(static method => - method.Name == nameof(HttpClientFactoryExtensions.AddRefitClient) + method.Name == nameof(HttpClientFactoryReflectionExtensions.AddRefitClient) && !method.IsGenericMethodDefinition && method.GetParameters() is [ diff --git a/src/tests/Refit.Tests/JsonLinesContentTypedTests.cs b/src/tests/Refit.Tests/JsonLinesContentTypedTests.cs index 289e482ba..796f4395f 100644 --- a/src/tests/Refit.Tests/JsonLinesContentTypedTests.cs +++ b/src/tests/Refit.Tests/JsonLinesContentTypedTests.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. using System.Runtime.CompilerServices; -using System.Text.Json.Serialization; namespace Refit.Tests; @@ -28,9 +27,6 @@ public class JsonLinesContentTypedTests /// The serializer used directly by these tests. private static readonly SystemTextJsonContentSerializer Serializer = new(); - /// The options used by the "converter handles object" fallback test: a converter that reports it can convert . - private static readonly System.Text.Json.JsonSerializerOptions ObjectConverterOptions = new() { Converters = { new ObjectConverter() } }; - /// The timeout used by every wait in the flush ordering test, so a regression fails instead of hanging. private static readonly TimeSpan FlushWaitTimeout = TimeSpan.FromSeconds(10); @@ -157,6 +153,23 @@ public async Task EnumeratorDisposedOnCompletion() await Assert.That(tracker.Disposed).IsTrue(); } + /// Verifies an enumerator whose disposal finishes asynchronously is still disposed when the destination fails. + /// A task representing the asynchronous test. + [Test] + public async Task EnumeratorWithAsynchronousDisposalIsDisposedWhenTheDestinationFails() + { + var tracker = new DisposeTracker(); + using var content = new JsonLinesContent(SlowDisposalAsync(tracker), Serializer); + + await Assert.That(async () => + { + await using var target = new WriteFailingStream(); + await content.CopyToAsync(target); + }).Throws(); + + await Assert.That(tracker.Disposed).IsTrue(); + } + /// Verifies the async enumerator is disposed when the producer throws. /// A task representing the asynchronous test. [Test] @@ -317,18 +330,6 @@ public async Task CreateTypedFallsBackForNonSystemTextJsonSerializer() await Assert.That(content).IsTypeOf(); } - /// Verifies the typed factory falls back to the untyped content when a converter can handle . - /// A task representing the asynchronous test. - [Test] - public async Task CreateTypedFallsBackWhenAConverterHandlesObject() - { - var settings = new RefitSettings(new SystemTextJsonContentSerializer(ObjectConverterOptions)); - - var content = GeneratedRequestRunner.CreateTypedJsonLinesBodyContent(settings, (IEnumerable)[new("1", "a")]); - - await Assert.That(content).IsTypeOf(); - } - /// Verifies the typed factory falls back to the untyped content for a non-sealed reference element type. /// A task representing the asynchronous test. [Test] @@ -427,6 +428,26 @@ private static async IAsyncEnumerable EmptyAsync() yield break; } + /// Produces elements and finishes its disposal asynchronously. + /// Records whether the enumerator was disposed. + /// The asynchronous sequence. + private static async IAsyncEnumerable SlowDisposalAsync(DisposeTracker tracker) + { + try + { + for (var i = 0; i < SampleElementCount; i++) + { + await Task.Yield(); + yield return new(i.ToString(), $"n{i}"); + } + } + finally + { + await Task.Yield(); + tracker.Disposed = true; + } + } + /// Produces elements while recording enumerator disposal, optionally throwing before a given index. /// Records whether the enumerator was disposed. /// The zero-based index to throw at, or -1 to never throw. @@ -539,33 +560,33 @@ private sealed class DisposeTracker internal bool Disposed { get; set; } } - /// A content serializer that is not . - private sealed class PlainSerializer : IHttpContentSerializer + /// A stream whose writes always fail. + private sealed class WriteFailingStream : MemoryStream { + /// The message every failed write carries. + private const string FailureMessage = "Write failed."; + /// - public HttpContent ToHttpContent(T item) => new StringContent(string.Empty); + public override void Write(byte[] buffer, int offset, int count) => throw new IOException(FailureMessage); /// - public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => - Task.FromResult(default); + public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) => + throw new IOException(FailureMessage); /// - public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) => null; + public override ValueTask WriteAsync(ReadOnlyMemory buffer, CancellationToken cancellationToken = default) => + throw new IOException(FailureMessage); } - /// A converter that reports it can convert , forcing the untyped fallback. - private sealed class ObjectConverter : JsonConverter + /// A content serializer that is not . + private sealed class PlainSerializer : IHttpContentSerializer { /// - public override bool CanConvert(Type typeToConvert) => typeToConvert == typeof(object); - - /// - public override object? Read(ref System.Text.Json.Utf8JsonReader reader, Type typeToConvert, System.Text.Json.JsonSerializerOptions options) => - null; + public HttpContent ToHttpContent(T item) => new StringContent(string.Empty); /// - public override void Write(System.Text.Json.Utf8JsonWriter writer, object value, System.Text.Json.JsonSerializerOptions options) => - writer.WriteNullValue(); + public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => + Task.FromResult(default); } #if NET8_0_OR_GREATER diff --git a/src/tests/Refit.Tests/JsonPropertyAttribute.cs b/src/tests/Refit.Tests/JsonPropertyAttribute.cs new file mode 100644 index 000000000..e98391392 --- /dev/null +++ b/src/tests/Refit.Tests/JsonPropertyAttribute.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. +using System; + +// This stand-in has the same full name as Newtonsoft.Json's attribute so the by-name lookup can be tested here +// without taking a Newtonsoft.Json reference in this test project. +namespace Newtonsoft.Json; + +/// Stand-in for Newtonsoft.Json's property-name attribute. +[AttributeUsage(AttributeTargets.Property)] +public sealed class JsonPropertyAttribute : Attribute +{ + /// Initializes a new instance of the class. + /// The serialized property name. + public JsonPropertyAttribute(string propertyName) => PropertyName = propertyName; + + /// Gets the serialized property name. + public string PropertyName { get; } +} diff --git a/src/tests/Refit.Tests/MethodOverladTests.cs b/src/tests/Refit.Tests/MethodOverladTests.cs index 45bbac3ef..9acccbd1f 100644 --- a/src/tests/Refit.Tests/MethodOverladTests.cs +++ b/src/tests/Refit.Tests/MethodOverladTests.cs @@ -111,7 +111,7 @@ public async Task GenericMethodOverloadTest4() const int headerValue = 99; var result = await fixture.Get("foo", headerValue); - await Assert.That(result.Args![ParamKey]).IsEqualTo("foo"); + await Assert.That(result.Args![ParamKey]?.ToString()).IsEqualTo("foo"); } /// Verifies the generic Get overload with header and parameter types swapped. @@ -132,7 +132,7 @@ public async Task GenericMethodOverloadTest5() const int paramValue = 99; var result = await fixture.Get(paramValue, "foo"); - await Assert.That(result.Args![ParamKey]).IsEqualTo("99"); + await Assert.That(result.Args![ParamKey]?.ToString()).IsEqualTo("99"); } /// Verifies the two-type-argument generic Get overload. diff --git a/src/tests/Refit.Tests/MultipartTests.cs b/src/tests/Refit.Tests/MultipartTests.cs index d97f69db1..cb1ddbcc7 100644 --- a/src/tests/Refit.Tests/MultipartTests.cs +++ b/src/tests/Refit.Tests/MultipartTests.cs @@ -508,9 +508,5 @@ public HttpContent ToHttpContent(T item) => HttpContent content, CancellationToken cancellationToken = default) => Task.FromResult(default(T)); - - /// - public string? GetFieldNameForProperty(PropertyInfo propertyInfo) => - null; } } diff --git a/src/tests/Refit.Tests/NonStreamingContentSerializer.cs b/src/tests/Refit.Tests/NonStreamingContentSerializer.cs index 75eb70e4d..91d323839 100644 --- a/src/tests/Refit.Tests/NonStreamingContentSerializer.cs +++ b/src/tests/Refit.Tests/NonStreamingContentSerializer.cs @@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis; using System.Net.Http; -using System.Reflection; using System.Threading; using System.Threading.Tasks; @@ -26,8 +25,4 @@ public sealed class NonStreamingContentSerializer : IHttpContentSerializer Justification = "Type parameter intentionally specified explicitly by callers.")] public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => _inner.FromHttpContentAsync(content, cancellationToken); - - /// - public string? GetFieldNameForProperty(PropertyInfo propertyInfo) => - _inner.GetFieldNameForProperty(propertyInfo); } diff --git a/src/tests/Refit.Tests/ObjectToInferredTypesConverterTests.cs b/src/tests/Refit.Tests/ObjectToInferredTypesConverterTests.cs new file mode 100644 index 000000000..c4711fe26 --- /dev/null +++ b/src/tests/Refit.Tests/ObjectToInferredTypesConverterTests.cs @@ -0,0 +1,105 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization.Metadata; + +namespace Refit.Tests; + +/// Verifies the opt-in converter that infers CLR primitives for values. +public sealed class ObjectToInferredTypesConverterTests +{ + /// The 64-bit value of the integral token used by the read tests. + private const long IntegralValue = 7L; + + /// The floating-point value of the fractional token used by the read tests. + private const double FloatingValue = 1.5; + + /// The options handed to the converter; the write path resolves runtime types through their resolver. + private static readonly JsonSerializerOptions Options = new() { TypeInfoResolver = new DefaultJsonTypeInfoResolver() }; + + /// Verifies each JSON token infers the expected CLR type and value. + /// The JSON token to read. + /// The expected value. + /// A task that represents the asynchronous test operation. + [Test] + [Arguments("true", true)] + [Arguments("false", false)] + [Arguments("7", IntegralValue)] + [Arguments("1.5", FloatingValue)] + [Arguments("\"Ada\"", "Ada")] + public async Task ReadInfersPrimitiveTokens(string json, object expected) + { + var value = Read(json); + + await Assert.That(value).IsEqualTo(expected); + await Assert.That(value!.GetType()).IsEqualTo(expected.GetType()); + } + + /// Verifies a date string infers . + /// A task that represents the asynchronous test operation. + [Test] + public async Task ReadInfersDateStrings() + { + var value = Read("\"2026-01-02T03:04:05\""); + + await Assert.That(value).IsTypeOf(); + } + + /// Verifies structured tokens stay . + /// The JSON token to read. + /// The expected value kind. + /// A task that represents the asynchronous test operation. + [Test] + [Arguments("{}", JsonValueKind.Object)] + [Arguments("[]", JsonValueKind.Array)] + [Arguments("null", JsonValueKind.Null)] + public async Task ReadKeepsStructuredTokensAsJsonElements(string json, JsonValueKind kind) + { + var value = Read(json); + + await Assert.That(await Assert.That(value).IsTypeOf()).IsNotDefault(); + await Assert.That(((JsonElement)value!).ValueKind).IsEqualTo(kind); + } + + /// Verifies a bare object writes as an empty JSON object instead of recursing. + /// A task that represents the asynchronous test operation. + [Test] + public async Task WriteEmitsEmptyObjectForBareObject() => + await Assert.That(Write(new())).IsEqualTo("{}"); + + /// Verifies other values write by their runtime type. + /// A task that represents the asynchronous test operation. + [Test] + public async Task WriteSerializesByRuntimeType() + { + await Assert.That(Write("Ada")).IsEqualTo("\"Ada\""); + await Assert.That(Write(IntegralValue)).IsEqualTo("7"); + } + + /// Reads one JSON token through the converter. + /// The JSON token. + /// The inferred value. + private static object? Read(string json) + { + var reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(json)); + _ = reader.Read(); + return new ObjectToInferredTypesConverter().Read(ref reader, typeof(object), Options); + } + + /// Writes one value through the converter. + /// The value to write. + /// The JSON text. + private static string Write(object value) + { + using var stream = new MemoryStream(); + using (var writer = new Utf8JsonWriter(stream)) + { + new ObjectToInferredTypesConverter().Write(writer, value, Options); + } + + return Encoding.UTF8.GetString(stream.ToArray()); + } +} diff --git a/src/tests/Refit.Tests/ParseQueryStringIntoTests.cs b/src/tests/Refit.Tests/ParseQueryStringIntoTests.cs new file mode 100644 index 000000000..4d0772c5d --- /dev/null +++ b/src/tests/Refit.Tests/ParseQueryStringIntoTests.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit.Tests; + +/// Verifies the query-string parser that seeds the reflection builder's query entries. +public sealed class ParseQueryStringIntoTests +{ + /// Verifies a null or empty query string adds nothing. + /// The query string to parse. + /// A task that represents the asynchronous test operation. + [Test] + [Arguments(null)] + [Arguments("")] + public async Task NullOrEmptyQueryStringAddsNothing(string? queryString) + { + List? entries = null; + + RequestBuilderImplementation.ParseQueryStringInto(queryString, ref entries); + + await Assert.That(entries).IsNull(); + } + + /// Verifies a query string is parsed with or without its leading question mark. + /// The query string to parse. + /// A task that represents the asynchronous test operation. + [Test] + [Arguments("?a=1")] + [Arguments("a=1")] + public async Task LeadingQuestionMarkIsOptional(string queryString) + { + List? entries = null; + + RequestBuilderImplementation.ParseQueryStringInto(queryString, ref entries); + + await Assert.That(entries!.Count).IsEqualTo(1); + await Assert.That(entries[0].Key).IsEqualTo("a"); + await Assert.That(entries[0].Value).IsEqualTo("1"); + } +} diff --git a/src/tests/Refit.Tests/Refit.Tests.csproj b/src/tests/Refit.Tests/Refit.Tests.csproj index fee34822d..1cff0d883 100644 --- a/src/tests/Refit.Tests/Refit.Tests.csproj +++ b/src/tests/Refit.Tests/Refit.Tests.csproj @@ -28,6 +28,7 @@ + diff --git a/src/tests/Refit.Tests/RefitSettingsJsonContextTests.cs b/src/tests/Refit.Tests/RefitSettingsJsonContextTests.cs index 2ca77e164..da27b92c1 100644 --- a/src/tests/Refit.Tests/RefitSettingsJsonContextTests.cs +++ b/src/tests/Refit.Tests/RefitSettingsJsonContextTests.cs @@ -1,7 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. -using System.Reflection; using System.Text.Json.Serialization.Metadata; namespace Refit.Tests; @@ -88,8 +87,5 @@ private sealed class UnsupportedContentSerializer : IHttpContentSerializer /// public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => throw new NotSupportedException(); - - /// - public string? GetFieldNameForProperty(PropertyInfo propertyInfo) => null; } } diff --git a/src/tests/Refit.Tests/ReflectionHooksTests.cs b/src/tests/Refit.Tests/ReflectionHooksTests.cs new file mode 100644 index 000000000..346753e2e --- /dev/null +++ b/src/tests/Refit.Tests/ReflectionHooksTests.cs @@ -0,0 +1,99 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit.Tests; + +/// Verifies the hook through which core Refit reaches the reflection-based form flattening. +public sealed class ReflectionHooksTests +{ + /// Verifies a missing flattener fails with a message that explains how to enable the reflection support. + /// A task that represents the asynchronous test operation. + [Test] + public async Task MissingFlattenerExplainsHowToEnableIt() + { + var exception = await Assert + .That(static () => ReflectionHooks.Require(null)) + .ThrowsExactly(); + + await Assert.That(exception!.Message).Contains("ReflectionSupport.EnsureRegistered"); + } + + /// Verifies missing JSON type metadata fails with a message that names the context and the reflection registration. + /// A task that represents the asynchronous test operation. + [Test] + public async Task MissingJsonResolverExplainsHowToSupplyMetadata() + { + var exception = await Assert + .That(static () => ReflectionHooks.CreateDefaultJsonResolver(null)) + .ThrowsExactly(); + + await Assert.That(exception!.Message).Contains("JsonSerializerContext"); + await Assert.That(exception.Message).Contains("ReflectionSupport.EnsureRegistered"); + } + + /// Verifies the default serializer reads and writes JSON once the reflection support is registered. + /// A task that represents the asynchronous test operation. + [Test] + public async Task DefaultSerializerUsesRegisteredReflectionResolver() + { + ReflectionSupport.EnsureRegistered(); + var serializer = new SystemTextJsonContentSerializer(); + + var roundTrip = serializer.DeserializeFromString("""{"child":{"name":"x"}}"""); + + await Assert.That(roundTrip!.Child!.Name).IsEqualTo("x"); + await Assert.That(serializer.SerializerOptions.TypeInfoResolver).IsNotNull(); + } + + /// Verifies a nested form value flattens once the reflection support is registered. + /// A task that represents the asynchronous test operation. + [Test] + public async Task NestedFormValueFlattensWhenSupportIsRegistered() + { + ReflectionSupport.EnsureRegistered(); + + var map = new FormValueMultimap(new NestedValue { Child = new() }, new RefitSettings()); + + await Assert.That(map.Keys.Single()).IsEqualTo("Child.Name"); + } + + /// Verifies registering twice keeps the first flattener. + /// A task that represents the asynchronous test operation. + [Test] + public async Task EnsureRegisteredIsIdempotent() + { + ReflectionSupport.EnsureRegistered(); + var first = ReflectionHooks.FormObjectFlattener; + + ReflectionSupport.EnsureRegistered(); + + await Assert.That(first).IsNotNull(); + await Assert.That(ReflectionHooks.FormObjectFlattener).IsSameReferenceAs(first); + } + + /// Verifies no reflection resolver is reported and no modifiers move when nothing is registered. + /// A task that represents the asynchronous test operation. + [Test] + public async Task UnregisteredResolverHooksDoNothing() + { + var resolver = new System.Text.Json.Serialization.Metadata.DefaultJsonTypeInfoResolver(); + + await Assert.That(ReflectionHooks.IsReflectionResolver(null, resolver)).IsFalse(); + await Assert.That(ReflectionHooks.CarryModifiers(null, resolver, [resolver])).IsSameReferenceAs(resolver); + } + + /// Form value whose property is a complex object, which needs the reflection flattener. + private sealed class NestedValue + { + /// Gets or sets the nested complex value. + public Inner? Child { get; set; } + } + + /// Complex value nested in . + private sealed class Inner + { + /// Gets or sets a scalar the flattener would emit. + public string? Name { get; set; } = "n"; + } +} diff --git a/src/tests/Refit.Tests/ReflectionSupportSetup.cs b/src/tests/Refit.Tests/ReflectionSupportSetup.cs new file mode 100644 index 000000000..a190860fe --- /dev/null +++ b/src/tests/Refit.Tests/ReflectionSupportSetup.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit.Tests; + +/// Registers the reflection support once so tests that build form maps directly do not depend on test order. +public static class ReflectionSupportSetup +{ + /// Registers the reflection form flattener before any test runs. + [Before(Assembly)] + public static void RegisterReflectionSupport() => ReflectionSupport.EnsureRegistered(); +} diff --git a/src/tests/Refit.Tests/RequestBuilderTests.Helpers.cs b/src/tests/Refit.Tests/RequestBuilderTests.Helpers.cs index 8f7bcbaa7..11042f992 100644 --- a/src/tests/Refit.Tests/RequestBuilderTests.Helpers.cs +++ b/src/tests/Refit.Tests/RequestBuilderTests.Helpers.cs @@ -4,7 +4,6 @@ using System.Collections; using System.Collections.Generic; -using System.Reflection; namespace Refit.Tests; @@ -366,7 +365,7 @@ private sealed class NestedQueryValue private sealed class BlankKeyUrlParameterFormatter : DefaultUrlParameterFormatter { /// - public override string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type) => + public override string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type) => value is string text && text == BlankDictionaryKey ? " " : base.Format(value, attributeProvider, type); @@ -376,7 +375,7 @@ private sealed class BlankKeyUrlParameterFormatter : DefaultUrlParameterFormatte private sealed class NullValueUrlParameterFormatter : DefaultUrlParameterFormatter { /// - public override string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type) => + public override string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type) => value is string text && text == NullFormattedQueryValue ? null : base.Format(value, attributeProvider, type); @@ -393,6 +392,6 @@ private sealed class NullFormUrlEncodedParameterFormatter : IFormUrlEncodedParam private sealed class AlwaysNullUrlParameterFormatter : DefaultUrlParameterFormatter { /// - public override string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type) => null; + public override string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type) => null; } } diff --git a/src/tests/Refit.Tests/RequestBuilderTests.cs b/src/tests/Refit.Tests/RequestBuilderTests.cs index dd47ff55a..d969438d4 100644 --- a/src/tests/Refit.Tests/RequestBuilderTests.cs +++ b/src/tests/Refit.Tests/RequestBuilderTests.cs @@ -65,9 +65,8 @@ public async Task RequestBuilderFactoryEntryPointsCreateBuilders() var genericBuilderWithSettings = RequestBuilder.ForType(new()); var typeBuilder = RequestBuilder.ForType(typeof(IDummyHttpApi)); var typeBuilderWithSettings = RequestBuilder.ForType(typeof(IDummyHttpApi), new()); - var factory = new RequestBuilderFactory(); - var factoryGenericBuilder = factory.Create(new()); - var factoryTypeBuilder = factory.Create(typeof(IDummyHttpApi), new()); + var factoryGenericBuilder = RequestBuilderFactory.Create(new()); + var factoryTypeBuilder = RequestBuilderFactory.Create(typeof(IDummyHttpApi), new()); await Assert.That(genericBuilder).IsNotNull(); await Assert.That(genericBuilderWithSettings).IsNotNull(); diff --git a/src/tests/Refit.Tests/ResponseTests.cs b/src/tests/Refit.Tests/ResponseTests.cs index 9da43b230..bb0112436 100644 --- a/src/tests/Refit.Tests/ResponseTests.cs +++ b/src/tests/Refit.Tests/ResponseTests.cs @@ -67,6 +67,10 @@ public sealed partial class ResponseTests private static readonly JsonSerializerOptions _caseSensitiveSerializerOptions = new() { PropertyNameCaseInsensitive = false }; + /// Options whose resolver describes no types, so no ProblemDetails metadata exists. + private static readonly JsonSerializerOptions EmptyResolverSerializerOptions = + new(JsonSerializerDefaults.Web) { TypeInfoResolver = System.Text.Json.Serialization.Metadata.JsonTypeInfoResolver.Combine() }; + /// Refit service used to exercise alias and response handling. public interface IMyAliasService { @@ -174,15 +178,13 @@ await Assert.That(actualException.ContentHeaders!.ContentType?.MediaType).IsEqua } /// - /// Verifies ValidationApiException deserializes ProblemDetails with the configured - /// IHttpContentSerializer instead of a hardcoded System.Text.Json instance. A - /// case-sensitive serializer is used here, so the camelCase DetailValue key must not map - /// to the PascalCase Detail property the way the old camelCase/case-insensitive - /// hardcoded options would have. + /// Verifies ValidationApiException reads ProblemDetails with Refit's own reader, so the result does not + /// depend on the configured serializer's options or type metadata. A case-sensitive serializer is + /// configured here, yet the camelCase detail key still maps to the Detail property. /// /// A task representing the asynchronous test. [Test] - public async Task ValidationApiExceptionUsesConfiguredContentSerializer() + public async Task ValidationApiExceptionReadsProblemDetailsIndependentlyOfConfiguredSerializer() { var expectedResponse = new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent("{\"Title\":\"mapped\",\"detail\":\"unmapped\"}"), }; expectedResponse.Content.Headers.ContentType = new( @@ -196,7 +198,29 @@ public async Task ValidationApiExceptionUsesConfiguredContentSerializer() await Assert.That(actualException!.Content).IsNotNull(); await Assert.That(actualException.Content!.Title).IsEqualTo("mapped"); - await Assert.That(actualException.Content.Detail).IsNull(); + await Assert.That(actualException.Content.Detail).IsEqualTo("unmapped"); + } + + /// Verifies problem details are read when the serializer's resolver describes no ProblemDetails metadata (issue 2368). + /// A task representing the asynchronous test. + [Test] + public async Task ValidationApiExceptionIsCreatedWhenResolverHasNoProblemDetailsMetadata() + { + var request = new HttpRequestMessage(HttpMethod.Post, "http://example.test/api/items"); + using var response = new HttpResponseMessage(HttpStatusCode.BadRequest) + { + RequestMessage = request, + Content = new StringContent( + "{\"status\":400,\"errors\":{\"Name\":[\"Name is required.\"]},\"traceId\":\"abc\"}", + System.Text.Encoding.UTF8, + ProblemJsonMediaType), + }; + + var exception = await ApiException.Create(request, request.Method, response, new(new SystemTextJsonContentSerializer(EmptyResolverSerializerOptions))); + + var validation = await Assert.That(exception).IsTypeOf(); + await Assert.That(validation!.Content!.Errors["Name"][0]).IsEqualTo("Name is required."); + await Assert.That(validation.Content.Extensions["traceId"]).IsEqualTo("abc"); } /// Verifies that EnsureSuccessStatusCodeAsync throws a ValidationApiException for a Bad Request in terms of RFC 7807. diff --git a/src/tests/Refit.Tests/RestServiceIntegrationTests.Inheritance.cs b/src/tests/Refit.Tests/RestServiceIntegrationTests.Inheritance.cs index f6899b61a..6ba214f26 100644 --- a/src/tests/Refit.Tests/RestServiceIntegrationTests.Inheritance.cs +++ b/src/tests/Refit.Tests/RestServiceIntegrationTests.Inheritance.cs @@ -214,9 +214,9 @@ public async Task DictionaryDynamicQueryParametersTest() var resp = await fixture.GetQuery(myParams); - await Assert.That(resp.Args![FirstNameKey]).IsEqualTo("John"); - await Assert.That(resp.Args[LastNameKey]).IsEqualTo(RamboLastName); - await Assert.That(resp.Args["Address_Zip"]).IsEqualTo("9999"); + await Assert.That(resp.Args![FirstNameKey]?.ToString()).IsEqualTo("John"); + await Assert.That(resp.Args[LastNameKey]?.ToString()).IsEqualTo(RamboLastName); + await Assert.That(resp.Args["Address_Zip"]?.ToString()).IsEqualTo("9999"); } /// Verifies complex dynamic query parameters work with an included parameter name. @@ -245,9 +245,9 @@ public async Task ComplexDynamicQueryparametersTestWithIncludeParameterName() var resp = await fixture.GetQueryWithIncludeParameterName(myParams); - await Assert.That(resp.Args!["search.FirstName"]).IsEqualTo("John"); - await Assert.That(resp.Args["search.LastName"]).IsEqualTo(RamboLastName); - await Assert.That(resp.Args["search.Addr.Zip"]).IsEqualTo("9999"); + await Assert.That(resp.Args!["search.FirstName"]?.ToString()).IsEqualTo("John"); + await Assert.That(resp.Args["search.LastName"]?.ToString()).IsEqualTo(RamboLastName); + await Assert.That(resp.Args["search.Addr.Zip"]?.ToString()).IsEqualTo("9999"); } /// Verifies a GET request works for a service declared outside a namespace. diff --git a/src/tests/Refit.Tests/RestServiceIntegrationTests.RequestBody.cs b/src/tests/Refit.Tests/RestServiceIntegrationTests.RequestBody.cs index e234c6789..57e5e80e2 100644 --- a/src/tests/Refit.Tests/RestServiceIntegrationTests.RequestBody.cs +++ b/src/tests/Refit.Tests/RestServiceIntegrationTests.RequestBody.cs @@ -349,7 +349,7 @@ public async Task GenericsWork() var result = await fixture.Get("foo", XRefitHeaderValue); await Assert.That(result.Url).IsEqualTo("http://httpbin.org/get?param=foo"); - await Assert.That(result.Args!["param"]).IsEqualTo("foo"); + await Assert.That(result.Args!["param"]?.ToString()).IsEqualTo("foo"); await Assert.That(result.Headers![RefitHeaderName]).IsEqualTo("99"); await handler.VerifyAllCalledAsync(); @@ -409,8 +409,8 @@ public async Task SimpleDynamicQueryparametersTest() var resp = await fixture.Get(myParams, XRefitHeaderValue); - await Assert.That(resp.Args![FirstNameKey]).IsEqualTo("John"); - await Assert.That(resp.Args["lName"]).IsEqualTo(RamboLastName); + await Assert.That(resp.Args![FirstNameKey]?.ToString()).IsEqualTo("John"); + await Assert.That(resp.Args["lName"]?.ToString()).IsEqualTo(RamboLastName); } /// Verifies complex dynamic query parameters are echoed correctly. @@ -452,9 +452,9 @@ public async Task ComplexDynamicQueryparametersTest() var resp = await fixture.GetQuery(myParams); - await Assert.That(resp.Args![FirstNameKey]).IsEqualTo("John"); - await Assert.That(resp.Args["LastName"]).IsEqualTo(RamboLastName); - await Assert.That(resp.Args["Addr_Zip"]).IsEqualTo("9999"); + await Assert.That(resp.Args![FirstNameKey]?.ToString()).IsEqualTo("John"); + await Assert.That(resp.Args["LastName"]?.ToString()).IsEqualTo(RamboLastName); + await Assert.That(resp.Args["Addr_Zip"]?.ToString()).IsEqualTo("9999"); } /// Verifies complex dynamic query parameters work for POST requests. @@ -496,9 +496,9 @@ public async Task ComplexPostDynamicQueryparametersTest() var resp = await fixture.PostQuery(myParams); - await Assert.That(resp.Args![FirstNameKey]).IsEqualTo("John"); - await Assert.That(resp.Args["LastName"]).IsEqualTo(RamboLastName); - await Assert.That(resp.Args["Addr_Zip"]).IsEqualTo("9999"); + await Assert.That(resp.Args![FirstNameKey]?.ToString()).IsEqualTo("John"); + await Assert.That(resp.Args["LastName"]?.ToString()).IsEqualTo(RamboLastName); + await Assert.That(resp.Args["Addr_Zip"]?.ToString()).IsEqualTo("9999"); } /// Verifies an object URL-encoded body flows through generated reflection-free form fields. diff --git a/src/tests/Refit.Tests/RouteBindingBranchTests.cs b/src/tests/Refit.Tests/RouteBindingBranchTests.cs new file mode 100644 index 000000000..deebb751a --- /dev/null +++ b/src/tests/Refit.Tests/RouteBindingBranchTests.cs @@ -0,0 +1,61 @@ +// Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. +// ReactiveUI and Contributors licenses this file to you under the MIT license. +// See the LICENSE file in the project root for full license information. + +namespace Refit.Tests; + +/// Verifies route placeholder binding paths that ordinary interfaces rarely reach. +public sealed class RouteBindingBranchTests +{ + /// The interface whose methods exercise the route binding paths. + public interface IRouteBindingApi + { + /// A round-trip placeholder with no matching parameter. + /// An unrelated parameter. + /// A task that represents the request. + [Get("/a/{**rest}")] + Task UnmatchedRoundTrip(string other); + + /// Two placeholders bound to properties of one request object. + /// The request object. + /// A task that represents the request. + [Get("/a/{request.Id}/{request.Name}")] + Task TwoProperties(RouteRequest request); + } + + /// Verifies a round-trip placeholder with no matching parameter is left in the path when unmatched placeholders are allowed. + /// A task that represents the asynchronous operation. + [Test] + public async Task UnmatchedRoundTripPlaceholderIsLeftInPlace() + { + var input = typeof(IRouteBindingApi); + var method = input.GetMethods().First(static x => x.Name == nameof(IRouteBindingApi.UnmatchedRoundTrip)); + + var fixture = new RestMethodInfoInternal(input, method, new() { AllowUnmatchedRouteParameters = true }); + + await Assert.That(fixture.ParameterMap.Count).IsEqualTo(0); + } + + /// Verifies two placeholders bound to properties of one object share a single property lookup. + /// A task that represents the asynchronous operation. + [Test] + public async Task TwoPropertyPlaceholdersBindToTheSameObject() + { + var input = typeof(IRouteBindingApi); + var method = input.GetMethods().First(static x => x.Name == nameof(IRouteBindingApi.TwoProperties)); + + var fixture = new RestMethodInfoInternal(input, method); + + await Assert.That(fixture.ParameterMap.Count).IsEqualTo(1); + } + + /// The request object whose properties fill route placeholders. + public sealed class RouteRequest + { + /// Gets or sets the identifier. + public int Id { get; set; } + + /// Gets or sets the name. + public string? Name { get; set; } + } +} diff --git a/src/tests/Refit.Tests/SerializedContentTests.ValueConversion.cs b/src/tests/Refit.Tests/SerializedContentTests.ValueConversion.cs index 01b05f727..7cd88bc11 100644 --- a/src/tests/Refit.Tests/SerializedContentTests.ValueConversion.cs +++ b/src/tests/Refit.Tests/SerializedContentTests.ValueConversion.cs @@ -2,7 +2,6 @@ // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. using System; -using System.IO; using System.Net.Http; using System.Text; using System.Text.Json; @@ -12,19 +11,36 @@ namespace Refit.Tests; -/// Verifies how the System.Text.Json content serializer converts JSON values and enums: object-value inference, number handling, and enum serialization and deserialization. +/// Verifies how the System.Text.Json content serializer converts JSON values and enums with the fast-path-eligible default options. public partial class SerializedContentTests { - /// Verifies that boolean JSON object values are inferred as . + /// Verifies the default options carry nothing that disables the System.Text.Json fast-path. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_InferBooleanObjectValues() + public async Task SystemTextJsonContentSerializer_DefaultOptions_AreFastPathEligible() { - var result = SystemTextJsonSerializer.Deserialize( - """{"value":true}""", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); + var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions(); + + await Assert.That(options.Converters).IsEmpty(); + await Assert.That(options.NumberHandling).IsEqualTo(JsonNumberHandling.Strict); + await Assert.That(options.ReferenceHandler).IsNull(); + await Assert.That(options.Encoder).IsNull(); + await Assert.That(options.DictionaryKeyPolicy).IsNull(); + await Assert.That(options.PropertyNamingPolicy).IsEqualTo(JsonNamingPolicy.CamelCase); + } + + /// Verifies the fast-path options carry nothing that disables the System.Text.Json fast-path. + /// A task that represents the asynchronous test operation. + [Test] + public async Task SystemTextJsonContentSerializer_FastPathOptions_AreFastPathEligible() + { + var options = SystemTextJsonContentSerializer.GetFastPathJsonSerializerOptions(); - await Assert.That(await Assert.That(result!.Value).IsTypeOf()).IsTrue(); + await Assert.That(options.Converters).IsEmpty(); + await Assert.That(options.NumberHandling).IsEqualTo(JsonNumberHandling.Strict); + await Assert.That(options.ReferenceHandler).IsNull(); + await Assert.That(options.Encoder).IsNull(); + await Assert.That(options.PropertyNamingPolicy).IsEqualTo(JsonNamingPolicy.CamelCase); } #if NET10_0_OR_GREATER @@ -42,56 +58,30 @@ await Assert #endif - /// Verifies false JSON object values are inferred as . - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_InferFalseObjectValues() - { - var result = SystemTextJsonSerializer.Deserialize( - """{"value":false}""", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(await Assert.That(result!.Value).IsTypeOf()).IsFalse(); - } - - /// Verifies that integral JSON object values are inferred as . + /// Verifies the default options reject numbers written as JSON strings. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_InferIntegralObjectValues() - { - var result = SystemTextJsonSerializer.Deserialize( - """{"value":42}""", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(await Assert.That(result!.Value).IsTypeOf()).IsEqualTo(ExpectedIntegralValue); - } - - /// Verifies that floating-point JSON object values are inferred as . - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_InferFloatingPointObjectValues() - { - var result = SystemTextJsonSerializer.Deserialize( - """{"value":42.5}""", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(await Assert.That(result!.Value).IsTypeOf()).IsEqualTo(ExpectedFloatingPointValue); - } + public async Task SystemTextJsonContentSerializer_DefaultOptions_RejectNumbersFromString() => + await Assert + .That(static () => SystemTextJsonSerializer.Deserialize( + """{"id":"123","amount":"9.99"}""", + SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions())) + .ThrowsExactly(); - /// Verifies the default options read numeric properties from JSON strings. + /// Verifies the default options read JSON numbers. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_ReadNumbersFromString() + public async Task SystemTextJsonContentSerializer_DefaultOptions_ReadNumbers() { var result = SystemTextJsonSerializer.Deserialize( - """{"id":"123","amount":"9.99"}""", + """{"id":123,"amount":9.99}""", SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); await Assert.That(result!.Id).IsEqualTo(ExpectedId); await Assert.That(result.Amount).IsEqualTo(ExpectedAmount); } - /// Verifies the default options still write numbers as JSON numbers, not strings. + /// Verifies the default options write numbers as JSON numbers, not strings. /// A task that represents the asynchronous test operation. [Test] public async Task SystemTextJsonContentSerializer_DefaultOptions_WriteNumbersAsNumbers() @@ -104,54 +94,7 @@ public async Task SystemTextJsonContentSerializer_DefaultOptions_WriteNumbersAsN await Assert.That(json).DoesNotContain("\"123\"", StringComparison.Ordinal); } - /// Verifies the default options expose . - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_NumberHandlingAllowsReadingFromString() => - await Assert - .That(SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions().NumberHandling) - .IsEqualTo(JsonNumberHandling.AllowReadingFromString); - - /// Verifies the fast-path options omit the settings that disable the System.Text.Json fast-path. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_FastPathOptions_AreFastPathEligible() - { - var options = SystemTextJsonContentSerializer.GetFastPathJsonSerializerOptions(); - - await Assert.That(options.Converters).IsEmpty(); - await Assert.That(options.NumberHandling).IsEqualTo(JsonNumberHandling.Strict); - await Assert.That(options.ReferenceHandler).IsNull(); - await Assert.That(options.Encoder).IsNull(); - await Assert.That(options.PropertyNamingPolicy).IsEqualTo(JsonNamingPolicy.CamelCase); - } - - /// Verifies that ISO date JSON object values are inferred as . - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_InferDateObjectValues() - { - var result = SystemTextJsonSerializer.Deserialize( - """{"value":"2024-01-02T03:04:05Z"}""", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(await Assert.That(result!.Value).IsTypeOf()) - .IsEqualTo(new(ExpectedYear, 1, ExpectedDay, ExpectedHour, ExpectedMinute, ExpectedSecond, DateTimeKind.Utc)); - } - - /// Verifies that string JSON object values are inferred as . - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_InferStringObjectValues() - { - var result = SystemTextJsonSerializer.Deserialize( - """{"value":"Road Runner"}""", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(await Assert.That(result!.Value).IsTypeOf()).IsEqualTo(RoadRunnerName); - } - - /// Verifies that nested JSON object values are deserialized as . + /// Verifies that object JSON values are deserialized as . /// A task that represents the asynchronous test operation. [Test] public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializeObjectValuesAsJsonElements() @@ -164,16 +107,20 @@ await Assert.That((await Assert.That(result!.Value).IsTypeOf()).Val .IsEqualTo(JsonValueKind.Object); } - /// Verifies that enum object values are serialized using camelCase. + /// Verifies that primitive object JSON values are deserialized as , not inferred CLR types. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_SerializeObjectEnumValuesAsCamelCase() + public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializePrimitiveObjectValuesAsJsonElements() { - var json = SystemTextJsonSerializer.Serialize( - new ObjectValueContainer { Value = CamelCaseEnum.ValueOne }, - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); + var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions(); - await Assert.That(json).IsEqualTo("""{"value":"valueOne"}"""); + var text = SystemTextJsonSerializer.Deserialize("""{"value":"Road Runner"}""", options); + var number = SystemTextJsonSerializer.Deserialize("""{"value":42}""", options); + var flag = SystemTextJsonSerializer.Deserialize("""{"value":true}""", options); + + await Assert.That((await Assert.That(text!.Value).IsTypeOf()).GetString()).IsEqualTo(RoadRunnerName); + await Assert.That((await Assert.That(number!.Value).IsTypeOf()).GetInt64()).IsEqualTo(ExpectedIntegralValue); + await Assert.That((await Assert.That(flag!.Value).IsTypeOf()).GetBoolean()).IsTrue(); } /// Verifies that null object values are serialized as JSON null. @@ -209,40 +156,16 @@ public async Task SystemTextJsonContentSerializer_DefaultOptions_UseResolverWhen await Assert.That(resolver.RequestedTypes).Contains(typeof(string)); } - /// Verifies that camelCase enum values are deserialized correctly. + /// Verifies that enums are serialized as numbers by the default options. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializeCamelCaseEnumValues() + public async Task SystemTextJsonContentSerializer_DefaultOptions_SerializeEnumValuesAsNumbers() { - var result = SystemTextJsonSerializer.Deserialize( - "\"valueOne\"", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(result).IsEqualTo(CamelCaseEnum.ValueOne); - } - - /// Verifies that enum values are deserialized case-insensitively. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializeCaseInsensitiveEnumValues() - { - var result = SystemTextJsonSerializer.Deserialize( - "\"VALUEONE\"", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(result).IsEqualTo(CamelCaseEnum.ValueOne); - } - - /// Verifies that already-lowercase enum values are deserialized correctly. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializeLowercaseEnumValues() - { - var result = SystemTextJsonSerializer.Deserialize( - "\"alreadyLowercase\"", + var json = SystemTextJsonSerializer.Serialize( + CamelCaseEnum.AlreadyLowercase, SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - await Assert.That(result).IsEqualTo(CamelCaseEnum.AlreadyLowercase); + await Assert.That(json).IsEqualTo("2"); } /// Verifies that numeric enum values are deserialized correctly. @@ -257,6 +180,16 @@ public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializeNume await Assert.That(result).IsEqualTo(CamelCaseEnum.AlreadyLowercase); } + /// Verifies that string enum names are rejected unless a source-generated context enables them. + /// A task that represents the asynchronous test operation. + [Test] + public async Task SystemTextJsonContentSerializer_DefaultOptions_RejectEnumNames() => + await Assert + .That(static () => SystemTextJsonSerializer.Deserialize( + "\"valueOne\"", + SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions())) + .ThrowsExactly(); + /// Verifies that unsigned numeric enum values are deserialized correctly. /// A task that represents the asynchronous test operation. [Test] @@ -281,30 +214,6 @@ public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializeNull await Assert.That(result).IsNull(); } - /// Verifies that an empty string deserializes to a null nullable enum. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializeEmptyNullableEnumValues() - { - var result = SystemTextJsonSerializer.Deserialize( - "\"\"", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(result).IsNull(); - } - - /// Verifies that a populated nullable enum string deserializes to its value. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializeValuedNullableEnumValues() - { - var result = SystemTextJsonSerializer.Deserialize( - "\"valueOne\"", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); - - await Assert.That(result).IsEqualTo(CamelCaseEnum.ValueOne); - } - /// Verifies that a numeric nullable enum token deserializes to its value. /// A task that represents the asynchronous test operation. [Test] @@ -327,36 +236,6 @@ await Assert.That( SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions())) .ThrowsExactly(); - /// Verifies that an empty string throws for a non-nullable enum. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_ThrowForEmptyNonNullableEnumValues() => - await Assert.That( - static () => SystemTextJsonSerializer.Deserialize( - "\"\"", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions())) - .ThrowsExactly(); - - /// Verifies that an unknown enum name throws. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_ThrowForInvalidEnumValues() => - await Assert.That( - static () => SystemTextJsonSerializer.Deserialize( - "\"notAValue\"", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions())) - .ThrowsExactly(); - - /// Verifies that unexpected JSON tokens throw when parsing enums. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_ThrowForUnexpectedTokensWhenParsingEnums() => - await Assert.That( - static () => SystemTextJsonSerializer.Deserialize( - "true", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions())) - .ThrowsExactly(); - /// Verifies that undefined enum values are serialized as numbers. /// A task that represents the asynchronous test operation. [Test] @@ -405,63 +284,46 @@ public async Task SystemTextJsonContentSerializer_DefaultOptions_SerializeUndefi await Assert.That(json).IsEqualTo("""{"9223372036854775808":"unknown"}"""); } - /// Verifies that lowercase enum names are serialized unchanged. + /// Verifies that a source-generated context with string enums round-trips through the serializer. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_SerializeLowercaseEnumNamesUnchanged() + public async Task SystemTextJsonContentSerializer_StringEnumContext_RoundTripsEnumNames() { - var json = SystemTextJsonSerializer.Serialize( - CamelCaseEnum.AlreadyLowercase, - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); + var serializer = new SystemTextJsonContentSerializer(StringEnumOptions); - await Assert.That(json).IsEqualTo("\"alreadyLowercase\""); + var content = serializer.ToHttpContent(new StringEnumEnvelope { Value = CamelCaseEnum.ValueOne }); + var serialized = await content.ReadAsStringAsync(); + var roundTrip = await serializer.FromHttpContentAsync( + new StringContent(serialized, Encoding.UTF8, JsonMediaType)); + + await Assert.That(serialized).Contains("\"ValueOne\""); + await Assert.That(roundTrip!.Value).IsEqualTo(CamelCaseEnum.ValueOne); } - /// Verifies that enum values are deserialized across a variety of casings. - /// The JSON string value to deserialize. + /// Verifies the opt-in reflection converters restore camelCase enum names. /// A task that represents the asynchronous test operation. [Test] - [Arguments("vAlUeOnE")] - [Arguments("ValueOne")] - [Arguments("VALUEONE")] - [Arguments("valueone")] - public async Task SystemTextJsonContentSerializer_DefaultOptions_DeserializesEnumValuesWithVariousCasings( - string jsonValue) + public async Task AddReflectionConverters_RoundTripsCamelCaseEnumNames() { - var result = SystemTextJsonSerializer.Deserialize( - $"\"{jsonValue}\"", - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); + var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions().AddReflectionConverters(); + + var json = SystemTextJsonSerializer.Serialize(CamelCaseEnum.ValueOne, options); + var result = SystemTextJsonSerializer.Deserialize("\"VALUEONE\"", options); + await Assert.That(json).IsEqualTo("\"valueOne\""); await Assert.That(result).IsEqualTo(CamelCaseEnum.ValueOne); } - /// Verifies that an exact-case match takes priority over case-insensitive matching when members differ only by case. + /// Verifies the opt-in reflection converters infer CLR primitives for object values. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_DefaultOptions_ExactCaseMatchTakesPriorityOverCaseInsensitiveWhenMembersDifferByCase() + public async Task AddReflectionConverters_InfersObjectValues() { - // When enum has members whose names differ only by case, the exact serialized form - // (camelCase) should be used first (case-sensitive), falling back to case-insensitive only - // for inputs that do not exactly match any known serialized form. - // CaseDifferentMembers.Alpha serializes to "alpha" (camelCase), - // CaseDifferentMembers.ALPHA serializes to "aLPHA" (camelCase). - // Exact-match lookups must correctly disambiguate these. - var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions(); + var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions().AddReflectionConverters(); - await Assert.That( - SystemTextJsonSerializer.Deserialize("\"alpha\"", options)) - .IsEqualTo(CaseDifferentMembers.Alpha); - await Assert.That( - SystemTextJsonSerializer.Deserialize("\"aLPHA\"", options)) - .IsEqualTo(CaseDifferentMembers.ALPHA); + var result = SystemTextJsonSerializer.Deserialize("""{"value":42}""", options); - // Field names are also accepted via exact match. - await Assert.That( - SystemTextJsonSerializer.Deserialize("\"Alpha\"", options)) - .IsEqualTo(CaseDifferentMembers.Alpha); - await Assert.That( - SystemTextJsonSerializer.Deserialize("\"ALPHA\"", options)) - .IsEqualTo(CaseDifferentMembers.ALPHA); + await Assert.That(await Assert.That(result!.Value).IsTypeOf()).IsEqualTo(ExpectedIntegralValue); } /// Verifies that source-generated metadata is used when provided to the serializer. @@ -533,36 +395,13 @@ public async Task SystemTextJsonContentSerializer_RoundTripsEnumDictionaryKeys() await Assert.That(roundTrip[CamelCaseEnum.AlreadyLowercase]).IsEqualTo("second"); } - /// Verifies nullable enum dictionary key conversion handles empty and non-empty property names. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_NullableEnumPropertyNamesRoundTripThroughConverter() - { - var (emptyNameValue, namedValue, json) = ReadAndWriteNullableEnumPropertyNames(); - - await Assert.That(emptyNameValue).IsNull(); - await Assert.That(namedValue).IsEqualTo(CamelCaseEnum.ValueOne); - await Assert.That(json).IsEqualTo("""{"":"empty","valueOne":"first"}"""); - } - - /// Verifies nullable enum values write null and concrete enum names through the custom converter. - /// A task that represents the asynchronous test operation. - [Test] - public async Task SystemTextJsonContentSerializer_NullableEnumValuesWriteThroughConverter() - { - var json = WriteNullableEnumValues(); - - await Assert.That(json).IsEqualTo("""[null,"valueOne"]"""); - } - #if NET9_0_OR_GREATER - /// Verifies that JsonStringEnumMemberName is honored when serializing and deserializing. + /// Verifies that JsonStringEnumMemberName is honored through a source-generated string-enum context. /// A task that represents the asynchronous test operation. [Test] public async Task SystemTextJsonContentSerializer_SupportsJsonStringEnumMemberName() { - var serializer = new SystemTextJsonContentSerializer( - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions()); + var serializer = new SystemTextJsonContentSerializer(StringEnumOptions); var content = serializer.ToHttpContent( new EnumMemberNameEnvelope { Status = EnumMemberNameStatus.TotallyReady }); @@ -575,14 +414,12 @@ public async Task SystemTextJsonContentSerializer_SupportsJsonStringEnumMemberNa await Assert.That(roundTrip!.Status).IsEqualTo(EnumMemberNameStatus.TotallyReady); } - /// Verifies that RestService uses the default enum converter with JsonStringEnumMemberName. + /// Verifies that RestService honors JsonStringEnumMemberName when a string-enum context is supplied. /// A task that represents the asynchronous test operation. [Test] - public async Task RestService_UsesDefaultEnumConverterWithJsonStringEnumMemberName() + public async Task RestService_HonorsJsonStringEnumMemberNameWithStringEnumContext() { - var settings = new RefitSettings( - new SystemTextJsonContentSerializer( - SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions())) + var settings = new RefitSettings(new SystemTextJsonContentSerializer(StringEnumOptions)) { HttpMessageHandlerFactory = static () => new StubHttpMessageHandler(static _ => Task.FromResult( @@ -617,54 +454,85 @@ public async Task RestService_DefaultSystemTextJsonSerializerHonorsJsonStringEnu } #endif - /// Exercises the nullable enum converter's property-name read and write paths. - /// The values read from property names and the JSON written through the converter. - private static (CamelCaseEnum? EmptyNameValue, CamelCaseEnum? NamedValue, string Json) ReadAndWriteNullableEnumPropertyNames() + /// Verifies a custom serializer that implements the reflection provider names fields itself. + /// A task that represents the asynchronous test operation. + [Test] + public async Task SerializerFieldNames_UsesCustomProviderWhenImplemented() { - var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions(); - var converter = (JsonConverter)options.GetConverter( - typeof(CamelCaseEnum?)); - var reader = new Utf8JsonReader("""{"":"empty","valueOne":"first"}"""u8); - _ = reader.Read(); - _ = reader.Read(); - var emptyNameValue = converter.ReadAsPropertyName(ref reader, typeof(CamelCaseEnum?), options); - _ = reader.Read(); - _ = reader.Read(); - var namedValue = converter.ReadAsPropertyName(ref reader, typeof(CamelCaseEnum?), options); - - using var stream = new MemoryStream(); - using (var writer = new Utf8JsonWriter(stream)) - { - writer.WriteStartObject(); + var property = typeof(SystemTextFieldNameModel).GetProperty(nameof(SystemTextFieldNameModel.Name)); - // The nullable converter intentionally supports null keys by writing an empty property name. - converter.WriteAsPropertyName(writer, null!, options); - writer.WriteStringValue("empty"); - converter.WriteAsPropertyName(writer, CamelCaseEnum.ValueOne, options); - writer.WriteStringValue(FirstEnumValue); - writer.WriteEndObject(); - } + var fieldName = SerializerFieldNames.Resolve(new ProviderTestSerializer(), property!); - return (emptyNameValue, namedValue, Encoding.UTF8.GetString(stream.ToArray())); + await Assert.That(fieldName).IsEqualTo("from-provider"); } - /// Writes nullable enum values through the converter directly. - /// The JSON written by the converter. - private static string WriteNullableEnumValues() + /// Verifies the Newtonsoft attribute is read by its type name, so no Newtonsoft reference is needed. + /// A task that represents the asynchronous test operation. + [Test] + public async Task SerializerFieldNames_ReadsNewtonsoftNameByTypeName() { - var options = SystemTextJsonContentSerializer.GetDefaultJsonSerializerOptions(); - var converter = (JsonConverter)options.GetConverter( - typeof(CamelCaseEnum?)); + var named = typeof(NewtonsoftNamedModel).GetProperty(nameof(NewtonsoftNamedModel.Named)); + var plain = typeof(NewtonsoftNamedModel).GetProperty(nameof(NewtonsoftNamedModel.Plain)); - using var stream = new MemoryStream(); - using (var writer = new Utf8JsonWriter(stream)) - { - writer.WriteStartArray(); - converter.Write(writer, null, options); - converter.Write(writer, CamelCaseEnum.ValueOne, options); - writer.WriteEndArray(); - } + await Assert.That(SerializerFieldNames.ResolveForStyle(ContentSerializerNameStyle.Newtonsoft, named!)).IsEqualTo("newtonsoft_name"); + await Assert.That(SerializerFieldNames.ResolveForStyle(ContentSerializerNameStyle.Newtonsoft, plain!)).IsNull(); + await Assert.That(SerializerFieldNames.ResolveForStyle( + ContentSerializerNameStyle.Newtonsoft, + typeof(NewtonsoftNamedModel).GetProperty(nameof(NewtonsoftNamedModel.Other))!)).IsNull(); + } - return Encoding.UTF8.GetString(stream.ToArray()); + /// Model whose property carries the stand-in Newtonsoft attribute. + internal sealed class NewtonsoftNamedModel + { + /// Gets or sets the property named through the stand-in attribute. + [global::Newtonsoft.Json.JsonProperty("newtonsoft_name")] + public string? Named { get; set; } + + /// Gets or sets a property with no attribute. + public string? Plain { get; set; } + + /// Gets or sets a property whose only attribute is not the Newtonsoft one. + [System.ComponentModel.Description("unrelated")] + public string? Other { get; set; } } + + /// Serializer that reports no name style and offers no provider. + internal sealed class ContentOnlyTestSerializer : IHttpContentSerializer + { + /// + public HttpContent ToHttpContent(T item) => new StringContent(string.Empty); + + /// + public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => + Task.FromResult(default); + } + + /// Serializer that names every field itself through the reflection provider. + internal sealed class ProviderTestSerializer : IHttpContentSerializer, IReflectionFieldNameProvider + { + /// + public HttpContent ToHttpContent(T item) => new StringContent(string.Empty); + + /// + public Task FromHttpContentAsync(HttpContent content, CancellationToken cancellationToken = default) => + Task.FromResult(default); + + /// + public string? GetFieldNameForProperty(System.Reflection.PropertyInfo propertyInfo) => "from-provider"; + } + + /// Container for an enum property used to verify string-enum source generation. + internal sealed class StringEnumEnvelope + { + /// Gets or sets the enum value. + public CamelCaseEnum Value { get; set; } + } + + /// Source-generated context that writes enums as strings. + [JsonSourceGenerationOptions(JsonSerializerDefaults.Web, UseStringEnumConverter = true)] + [JsonSerializable(typeof(StringEnumEnvelope))] +#if NET9_0_OR_GREATER + [JsonSerializable(typeof(EnumMemberNameEnvelope))] +#endif + internal sealed partial class StringEnumJsonSerializerContext : JsonSerializerContext; } diff --git a/src/tests/Refit.Tests/SerializedContentTests.cs b/src/tests/Refit.Tests/SerializedContentTests.cs index 65f08839a..6aabd5b2e 100644 --- a/src/tests/Refit.Tests/SerializedContentTests.cs +++ b/src/tests/Refit.Tests/SerializedContentTests.cs @@ -37,30 +37,12 @@ public partial class SerializedContentTests /// The expected inferred integral value for object-value inference tests. private const long ExpectedIntegralValue = 42L; - /// The expected inferred floating-point value for object-value inference tests. - private const double ExpectedFloatingPointValue = 42.5; - /// The expected identifier parsed from a numeric JSON string. private const int ExpectedId = 123; /// The expected amount parsed from a numeric JSON string. private const decimal ExpectedAmount = 9.99M; - /// The expected year component of the inferred date value. - private const int ExpectedYear = 2024; - - /// The expected day component of the inferred date value. - private const int ExpectedDay = 2; - - /// The expected hour component of the inferred date value. - private const int ExpectedHour = 3; - - /// The expected minute component of the inferred date value. - private const int ExpectedMinute = 4; - - /// The expected second component of the inferred date value. - private const int ExpectedSecond = 5; - /// The year component of the sample created-at date used in body-serialization round-trips. private const int SampleCreatedYear = 1949; @@ -79,6 +61,10 @@ public partial class SerializedContentTests /// The circuit-breaker timeout, in seconds, that bounds a body-serialization task run. private const int CircuitBreakerTimeoutSeconds = 30; + /// Web-default options over the string-enum context, shared so the options are built once. + private static readonly JsonSerializerOptions StringEnumOptions = + new(JsonSerializerDefaults.Web) { TypeInfoResolver = StringEnumJsonSerializerContext.Default }; + /// Serializer options carrying the source-generated polymorphic context, shared by the declared-base body test. private static readonly JsonSerializerOptions PolymorphicBaseSerializerOptions = new(JsonSerializerDefaults.Web) { TypeInfoResolver = PolymorphicRequestJsonSerializerContext.Default }; @@ -114,7 +100,7 @@ public enum EnumMemberNameColor #endif /// Enum whose members exercise camelCase serialization and case-insensitive deserialization. - private enum CamelCaseEnum + internal enum CamelCaseEnum { /// The first value, serialized as "valueOne". ValueOne = 1, @@ -335,44 +321,56 @@ public async Task StreamDeserialization_UsingSystemTextJsonContentSerializer_Set await Assert.That(json.Headers.ContentType.MediaType).IsEqualTo(JsonMediaType); } - /// Verifies that the System.Text.Json content serializer returns the JsonPropertyName for a property. + /// Verifies that Refit resolves the JsonPropertyName for a property with the System.Text.Json serializer. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_GetFieldNameForProperty_ReturnsJsonPropertyName() + public async Task SerializerFieldNames_SystemTextJson_ReturnsJsonPropertyName() { var serializer = new SystemTextJsonContentSerializer(); var property = typeof(SystemTextFieldNameModel).GetProperty( nameof(SystemTextFieldNameModel.Name)); - var fieldName = serializer.GetFieldNameForProperty(property!); + var fieldName = SerializerFieldNames.Resolve(serializer, property!); await Assert.That(fieldName).IsEqualTo("json_name"); } - /// Verifies that the System.Text.Json content serializer returns null without a JsonPropertyName attribute. + /// Verifies that Refit resolves no name without a JsonPropertyName attribute. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_GetFieldNameForProperty_ReturnsNullWithoutJsonPropertyNameAttribute() + public async Task SerializerFieldNames_SystemTextJson_ReturnsNullWithoutJsonPropertyNameAttribute() { var serializer = new SystemTextJsonContentSerializer(); var property = typeof(SystemTextFieldNameModel).GetProperty( nameof(SystemTextFieldNameModel.Unaliased)); - var fieldName = serializer.GetFieldNameForProperty(property!); + var fieldName = SerializerFieldNames.Resolve(serializer, property!); await Assert.That(fieldName).IsNull(); } - /// Verifies that the System.Text.Json content serializer throws when the property argument is null. + /// Verifies that name resolution throws when the property argument is null. /// A task that represents the asynchronous test operation. [Test] - public async Task SystemTextJsonContentSerializer_GetFieldNameForProperty_ThrowsForNullProperty() + public async Task SerializerFieldNames_ThrowsForNullProperty() { var serializer = new SystemTextJsonContentSerializer(); - var exception = await Assert.That(() => serializer.GetFieldNameForProperty(null!)).ThrowsExactly(); + var exception = await Assert.That(() => SerializerFieldNames.Resolve(serializer, null!)).ThrowsExactly(); - await Assert.That(exception!.ParamName).IsEqualTo("propertyInfo"); + await Assert.That(exception!.ParamName).IsEqualTo("property"); + } + + /// Verifies that a serializer with no name style and no provider contributes no name. + /// A task that represents the asynchronous test operation. + [Test] + public async Task SerializerFieldNames_ReturnsNullForSerializerWithoutNameStyle() + { + var property = typeof(SystemTextFieldNameModel).GetProperty(nameof(SystemTextFieldNameModel.Name)); + + var fieldName = SerializerFieldNames.Resolve(new ContentOnlyTestSerializer(), property!); + + await Assert.That(fieldName).IsNull(); } /// Verifies that RestService can use source-generated System.Text.Json metadata. diff --git a/src/tests/Refit.Tests/SystemTextJsonQueryConverterTests.cs b/src/tests/Refit.Tests/SystemTextJsonQueryConverterTests.cs index 806cef2d9..8e595aaed 100644 --- a/src/tests/Refit.Tests/SystemTextJsonQueryConverterTests.cs +++ b/src/tests/Refit.Tests/SystemTextJsonQueryConverterTests.cs @@ -174,7 +174,7 @@ private sealed class RecursiveNode } /// A minimal non-System.Text.Json serializer used to trip the converter's serializer guard. - private sealed class NonJsonSerializer : IHttpContentSerializer + private sealed class NonJsonSerializer : IHttpContentSerializer, IReflectionFieldNameProvider { /// public HttpContent ToHttpContent(T item) => new StringContent(string.Empty); diff --git a/src/tests/Refit.Tests/TemperatureUrlParameterFormatter.cs b/src/tests/Refit.Tests/TemperatureUrlParameterFormatter.cs index 4ec7558d3..3c2c7ba09 100644 --- a/src/tests/Refit.Tests/TemperatureUrlParameterFormatter.cs +++ b/src/tests/Refit.Tests/TemperatureUrlParameterFormatter.cs @@ -1,9 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. - -using System.Reflection; - namespace Refit.Tests; /// A URL parameter formatter that renders a with a trailing deg suffix, @@ -11,6 +8,6 @@ namespace Refit.Tests; public sealed class TemperatureUrlParameterFormatter : IUrlParameterFormatter { /// - public string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type) => + public string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type) => value is Temperature temperature ? $"{temperature.Celsius}deg" : value?.ToString(); } diff --git a/src/tests/Refit.Tests/TestEnumUrlParameterFormatter.cs b/src/tests/Refit.Tests/TestEnumUrlParameterFormatter.cs index 4f48959c0..92c2e90d1 100644 --- a/src/tests/Refit.Tests/TestEnumUrlParameterFormatter.cs +++ b/src/tests/Refit.Tests/TestEnumUrlParameterFormatter.cs @@ -1,9 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. - -using System.Reflection; - namespace Refit.Tests; /// Converts enums to ints and adds a suffix to strings to test key and value formatting. @@ -19,7 +16,7 @@ public class TestEnumUrlParameterFormatter : DefaultUrlParameterFormatter /// The formatted parameter value. public override string? Format( object? value, - ICustomAttributeProvider attributeProvider, + IParameterAttributeProvider attributeProvider, Type type) { if (value is TestEnum enumValue) diff --git a/src/tests/Refit.Tests/TestEnumerableUrlParameterFormatter.cs b/src/tests/Refit.Tests/TestEnumerableUrlParameterFormatter.cs index 38f886de2..0e8309486 100644 --- a/src/tests/Refit.Tests/TestEnumerableUrlParameterFormatter.cs +++ b/src/tests/Refit.Tests/TestEnumerableUrlParameterFormatter.cs @@ -3,7 +3,6 @@ // See the LICENSE file in the project root for full license information. using System.Collections; -using System.Reflection; namespace Refit.Tests; @@ -17,7 +16,7 @@ public class TestEnumerableUrlParameterFormatter : DefaultUrlParameterFormatter /// The formatted parameter value. public override string? Format( object? value, - ICustomAttributeProvider attributeProvider, + IParameterAttributeProvider attributeProvider, Type type) => value switch { diff --git a/src/tests/Refit.Tests/TestUrlFormatter.cs b/src/tests/Refit.Tests/TestUrlFormatter.cs index ca4b0e5d2..94a1a6cf5 100644 --- a/src/tests/Refit.Tests/TestUrlFormatter.cs +++ b/src/tests/Refit.Tests/TestUrlFormatter.cs @@ -43,9 +43,9 @@ public TestUrlFormatter( /// The declared type of the value. /// The string representation of the value. /// or does not match the expectation recorded for this invocation. - public string? Format(object? value, ICustomAttributeProvider attributeProvider, Type type) + public string? Format(object? value, IParameterAttributeProvider attributeProvider, Type type) { - if (!SameMetadata(attributeProvider, _expectedAttributeProviders[_index])) + if (!SameAttributes(attributeProvider, _expectedAttributeProviders[_index])) { throw new InvalidOperationException( $"Unexpected attribute provider at index {_index}."); @@ -69,47 +69,24 @@ public async Task AssertNoOutstandingAssertions() } /// - /// Compares two attribute providers by stable metadata identity rather than reference. - /// The runtime's reflection cache can evict and return a different - /// (or ) instance for the same member under memory pressure, so a - /// reference comparison is unreliable across separate reflection lookups. - /// - /// The attribute provider received by the formatter. - /// The attribute provider the test expects. - /// if both describe the same metadata element. - private static bool SameMetadata(ICustomAttributeProvider actual, ICustomAttributeProvider expected) => - ReferenceEquals(actual, expected) - || (actual, expected) switch - { - (ParameterInfo a, ParameterInfo b) => - a.Position == b.Position - && a.Member.MetadataToken == b.Member.MetadataToken - && a.Member.Module == b.Member.Module, - (MemberInfo a, MemberInfo b) => - a.MetadataToken == b.MetadataToken && a.Module == b.Module, - _ => SameAttributes(actual, expected), - }; - - /// - /// Compares two providers of different kinds by the attributes they expose. Generated request - /// building supplies a synthetic instead of the - /// reflection , so the formatter matches on the attribute metadata both - /// providers carry rather than on the concrete provider type. + /// Compares the received provider with the expected reflection element by the attribute types both expose. + /// Generated and reflection request building supply different provider types, and the runtime's reflection + /// cache can return a different instance for the same member, so identity is not a reliable comparison. /// /// The attribute provider received by the formatter. /// The attribute provider the test expects. /// if both expose the same attribute types. - private static bool SameAttributes(ICustomAttributeProvider actual, ICustomAttributeProvider expected) + private static bool SameAttributes(IParameterAttributeProvider actual, ICustomAttributeProvider expected) { - static string[] AttributeTypeNames(ICustomAttributeProvider provider) + static string[] Names(IEnumerable attributes) { - var names = provider.GetCustomAttributes(false) + var names = attributes .Select(static attribute => attribute.GetType().FullName ?? string.Empty) .ToArray(); Array.Sort(names, StringComparer.Ordinal); return names; } - return AttributeTypeNames(actual).SequenceEqual(AttributeTypeNames(expected)); + return Names(actual.GetCustomAttributes(false)).SequenceEqual(Names(expected.GetCustomAttributes(false))); } } diff --git a/src/tests/Refit.Tests/TestUrlParameterFormatter.cs b/src/tests/Refit.Tests/TestUrlParameterFormatter.cs index aad63f2b0..f00f182e2 100644 --- a/src/tests/Refit.Tests/TestUrlParameterFormatter.cs +++ b/src/tests/Refit.Tests/TestUrlParameterFormatter.cs @@ -1,9 +1,6 @@ // Copyright (c) 2019-2026 ReactiveUI and Contributors. All rights reserved. // ReactiveUI and Contributors licenses this file to you under the MIT license. // See the LICENSE file in the project root for full license information. - -using System.Reflection; - namespace Refit.Tests; /// A URL parameter formatter that always returns a constant value. @@ -21,5 +18,5 @@ public class TestUrlParameterFormatter : IUrlParameterFormatter /// The attribute provider for the parameter. /// The declared type of the parameter. /// The configured constant value. - public string Format(object? value, ICustomAttributeProvider attributeProvider, Type type) => _constantParameterOutput; + public string Format(object? value, IParameterAttributeProvider attributeProvider, Type type) => _constantParameterOutput; } diff --git a/src/tests/Refit.Tests/XmlContentSerializerTests.cs b/src/tests/Refit.Tests/XmlContentSerializerTests.cs index 52e5a1698..fa3b8dbad 100644 --- a/src/tests/Refit.Tests/XmlContentSerializerTests.cs +++ b/src/tests/Refit.Tests/XmlContentSerializerTests.cs @@ -154,12 +154,12 @@ public async Task GuardsAndXmlFieldNamesShouldWork() await Assert.That(static () => new XmlContentSerializer(null!)).ThrowsExactly(); await Assert.That(() => sut.ToHttpContent(null!)).ThrowsExactly(); - await Assert.That(() => sut.GetFieldNameForProperty(null!)).ThrowsExactly(); - await Assert.That(sut.GetFieldNameForProperty(typeof(XmlFieldNameDto).GetProperty(nameof(XmlFieldNameDto.Element))!)) + await Assert.That(() => SerializerFieldNames.Resolve(sut, null!)).ThrowsExactly(); + await Assert.That(SerializerFieldNames.Resolve(sut, typeof(XmlFieldNameDto).GetProperty(nameof(XmlFieldNameDto.Element))!)) .IsEqualTo("element-name"); - await Assert.That(sut.GetFieldNameForProperty(typeof(XmlFieldNameDto).GetProperty(nameof(XmlFieldNameDto.Attribute))!)) + await Assert.That(SerializerFieldNames.Resolve(sut, typeof(XmlFieldNameDto).GetProperty(nameof(XmlFieldNameDto.Attribute))!)) .IsEqualTo("attribute-name"); - await Assert.That(sut.GetFieldNameForProperty(typeof(XmlFieldNameDto).GetProperty(nameof(XmlFieldNameDto.Unannotated))!)) + await Assert.That(SerializerFieldNames.Resolve(sut, typeof(XmlFieldNameDto).GetProperty(nameof(XmlFieldNameDto.Unannotated))!)) .IsNull(); }