diff --git a/Refit.HttpClientFactory/Refit.HttpClientFactory.csproj b/Refit.HttpClientFactory/Refit.HttpClientFactory.csproj
index 63f716d41..a6f6558f2 100644
--- a/Refit.HttpClientFactory/Refit.HttpClientFactory.csproj
+++ b/Refit.HttpClientFactory/Refit.HttpClientFactory.csproj
@@ -5,6 +5,7 @@
Refit HTTP Client Factory Extensions
$(RefitTargets)
enable
+ true
diff --git a/Refit.Newtonsoft.Json/Refit.Newtonsoft.Json.csproj b/Refit.Newtonsoft.Json/Refit.Newtonsoft.Json.csproj
index e30550800..2d984f915 100644
--- a/Refit.Newtonsoft.Json/Refit.Newtonsoft.Json.csproj
+++ b/Refit.Newtonsoft.Json/Refit.Newtonsoft.Json.csproj
@@ -7,6 +7,7 @@
true
Refit
enable
+ true
diff --git a/Refit.Tests/API/_snapshots/ApiApprovalTests.Refit.DotNet10_0.verified.txt b/Refit.Tests/API/_snapshots/ApiApprovalTests.Refit.DotNet10_0.verified.txt
index bbb331d37..da6125aa0 100644
--- a/Refit.Tests/API/_snapshots/ApiApprovalTests.Refit.DotNet10_0.verified.txt
+++ b/Refit.Tests/API/_snapshots/ApiApprovalTests.Refit.DotNet10_0.verified.txt
@@ -1,4 +1,5 @@
-[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory")]
+[assembly: System.Runtime.CompilerServices.DisableRuntimeMarshalling]
+[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.HttpClientFactory")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Newtonsoft.Json")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Tests")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Refit.Xml")]
@@ -367,10 +368,14 @@ namespace Refit
}
public static class RequestBuilder
{
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Refit uses reflection to analyze interface methods. Ensure referenced interfaces " +
+ "and DTOs are preserved when trimming.")]
public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType) { }
- public static Refit.IRequestBuilder ForType(System.Type refitInterfaceType, Refit.RefitSettings? settings) { }
- public static Refit.IRequestBuilder ForType() { }
- public static Refit.IRequestBuilder ForType(Refit.RefitSettings? settings) { }
+ [System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Refit uses reflection to analyze interface methods. Ensure referenced interfaces " +
+ "and DTOs are preserved when trimming.")]
+ public static Refit.IRequestBuilder ForType([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.None | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods)] System.Type refitInterfaceType, Refit.RefitSettings? settings) { }
+ public static Refit.IRequestBuilder ForType<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.None | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods)] T>() { }
+ public static Refit.IRequestBuilder ForType<[System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembers(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.None | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.PublicMethods | System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.NonPublicMethods)] T>(Refit.RefitSettings? settings) { }
}
public class RestMethodInfo : System.IEquatable
{
diff --git a/Refit.Tests/Refit.Tests.csproj b/Refit.Tests/Refit.Tests.csproj
index 198617bdf..2b87861f8 100644
--- a/Refit.Tests/Refit.Tests.csproj
+++ b/Refit.Tests/Refit.Tests.csproj
@@ -7,7 +7,7 @@
false
https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
- $(NoWarn);CS1591;CA1819;CA2000;CA2007;CA1056;CA1707;CA1861;xUnit1031
+ $(NoWarn);CS1591;CA1819;CA2000;CA2007;CA1056;CA1707;CA1861;CA1515;xUnit1031
6.0.0
false
diff --git a/Refit.Xml/Refit.Xml.csproj b/Refit.Xml/Refit.Xml.csproj
index e7d37c92e..7a26c5df1 100644
--- a/Refit.Xml/Refit.Xml.csproj
+++ b/Refit.Xml/Refit.Xml.csproj
@@ -7,6 +7,7 @@
true
Refit
enable
+ true
diff --git a/Refit/AotCompatibility.cs b/Refit/AotCompatibility.cs
new file mode 100644
index 000000000..bdb57d679
--- /dev/null
+++ b/Refit/AotCompatibility.cs
@@ -0,0 +1,14 @@
+using System.Runtime.CompilerServices;
+using System.Diagnostics.CodeAnalysis;
+#if NET7_0_OR_GREATER
+using System.Runtime.InteropServices;
+#endif
+
+namespace Refit
+{
+ internal static class AotCompatibility
+ {
+ // Intentionally left blank to avoid changing public API surface (e.g., assembly-level attributes)
+ // while keeping a central place for any future AOT-related initializers if needed.
+ }
+}
diff --git a/Refit/Polyfills.Trimming.cs b/Refit/Polyfills.Trimming.cs
new file mode 100644
index 000000000..600852f9b
--- /dev/null
+++ b/Refit/Polyfills.Trimming.cs
@@ -0,0 +1,19 @@
+#if NETSTANDARD2_0 || NET462
+namespace System.Diagnostics.CodeAnalysis
+{
+ [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Method | System.AttributeTargets.Property | System.AttributeTargets.Event, Inherited = false)]
+ internal sealed class RequiresUnreferencedCodeAttribute : System.Attribute
+ {
+ public RequiresUnreferencedCodeAttribute(string message) => Message = message;
+ public string Message { get; }
+ public string? Url { get; set; }
+ }
+
+ [System.AttributeUsage(System.AttributeTargets.Constructor | System.AttributeTargets.Method, AllowMultiple = true)]
+ internal sealed class DynamicDependencyAttribute : System.Attribute
+ {
+ public DynamicDependencyAttribute(DynamicallyAccessedMemberTypes memberTypes, System.Type type) { }
+ public DynamicDependencyAttribute(string memberSignature, System.Type type) { }
+ }
+}
+#endif
diff --git a/Refit/Refit.csproj b/Refit/Refit.csproj
index ede96070f..cb328d0e3 100644
--- a/Refit/Refit.csproj
+++ b/Refit/Refit.csproj
@@ -9,11 +9,23 @@
true
+ true
+ link
+ true
+ true
+
+
+
+
+ false
+
+
+ true
-
-
+
+
diff --git a/Refit/RequestBuilder.cs b/Refit/RequestBuilder.cs
index aa06da38b..0eb6ca62b 100644
--- a/Refit/RequestBuilder.cs
+++ b/Refit/RequestBuilder.cs
@@ -1,19 +1,12 @@
using System.Net.Http;
+#if NET10_0_OR_GREATER
+using System.Diagnostics.CodeAnalysis;
+#endif
namespace Refit
{
- ///
- /// IRequestBuilder.
- ///
public interface IRequestBuilder
{
- ///
- /// Builds the rest result function for method.
- ///
- /// Name of the method.
- /// The parameter types.
- /// The generic argument types.
- ///
Func BuildRestResultFuncForMethod(
string methodName,
Type[]? parameterTypes = null,
@@ -21,51 +14,64 @@ public interface IRequestBuilder
);
}
- ///
- ///
- ///
- ///
public interface IRequestBuilder : IRequestBuilder { }
- ///
- /// RequestBuilder.
- ///
public static class RequestBuilder
{
static readonly RequestBuilderFactory PlatformRequestBuilderFactory = new();
- ///
- /// Fors the type.
- ///
- ///
- /// The settings.
- ///
+#if NET10_0_OR_GREATER
+ public static IRequestBuilder ForType< [
+ DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.None |
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods
+ )] T >(RefitSettings? settings) =>
+ PlatformRequestBuilderFactory.Create(settings);
+#else
public static IRequestBuilder ForType(RefitSettings? settings) =>
PlatformRequestBuilderFactory.Create(settings);
+#endif
- ///
- /// Fors the type.
- ///
- ///
- ///
+#if NET10_0_OR_GREATER
+ public static IRequestBuilder ForType< [
+ DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.None |
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods
+ )] T >() =>
+ PlatformRequestBuilderFactory.Create(null);
+#else
public static IRequestBuilder ForType() =>
PlatformRequestBuilderFactory.Create(null);
+#endif
- ///
- /// Fors the type.
- ///
- /// Type of the refit interface.
- /// The settings.
- ///
- public static IRequestBuilder ForType(Type refitInterfaceType, RefitSettings? settings) =>
- PlatformRequestBuilderFactory.Create(refitInterfaceType, settings);
+#if NET10_0_OR_GREATER
+ [RequiresUnreferencedCode("Refit uses reflection to analyze interface methods. Ensure referenced interfaces and DTOs are preserved when trimming.")]
+ public static IRequestBuilder ForType(
+ [DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.None |
+ DynamicallyAccessedMemberTypes.PublicMethods |
+ DynamicallyAccessedMemberTypes.NonPublicMethods
+ )] Type refitInterfaceType,
+ RefitSettings? settings
+ )
+#else
+ public static IRequestBuilder ForType(
+ Type refitInterfaceType,
+ RefitSettings? settings
+ )
+#endif
+ {
+ return new CachedRequestBuilderImplementation(
+ new RequestBuilderImplementation(refitInterfaceType, settings)
+ );
+ }
- ///
- /// Fors the type.
- ///
- /// Type of the refit interface.
- ///
+#if NET10_0_OR_GREATER
+ [RequiresUnreferencedCode("Refit uses reflection to analyze interface methods. Ensure referenced interfaces and DTOs are preserved when trimming.")]
+#endif
public static IRequestBuilder ForType(Type refitInterfaceType) =>
- PlatformRequestBuilderFactory.Create(refitInterfaceType, null);
+ ForType(refitInterfaceType, null);
}
}
diff --git a/Refit/RequestBuilderImplementation.cs b/Refit/RequestBuilderImplementation.cs
index f7fddd4d4..b520ff7d2 100644
--- a/Refit/RequestBuilderImplementation.cs
+++ b/Refit/RequestBuilderImplementation.cs
@@ -1,17 +1,31 @@
using System.Collections;
using System.Collections.Concurrent;
using System.Diagnostics;
-using System.Diagnostics.CodeAnalysis;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Web;
+#if NET5_0_OR_GREATER
+using System.Diagnostics.CodeAnalysis;
+#endif
namespace Refit
{
- class RequestBuilderImplementation(RefitSettings? refitSettings = null)
- : RequestBuilderImplementation(typeof(TApi), refitSettings),
- IRequestBuilder { }
+#if NET5_0_OR_GREATER
+ class RequestBuilderImplementation<
+ [
+ DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods
+ )] TApi> : RequestBuilderImplementation, IRequestBuilder
+#else
+ class RequestBuilderImplementation : RequestBuilderImplementation, IRequestBuilder
+#endif
+ {
+ public RequestBuilderImplementation(RefitSettings? refitSettings = null)
+ : base(typeof(TApi), refitSettings)
+ {
+ }
+ }
partial class RequestBuilderImplementation : IRequestBuilder
{
@@ -27,7 +41,15 @@ readonly ConcurrentDictionary<
readonly RefitSettings settings;
public Type TargetType { get; }
+#if NET5_0_OR_GREATER
+ [RequiresUnreferencedCode("RequestBuilder uses reflection on the provided Refit interface and DTO types. Ensure necessary members are preserved when trimming.")]
+#endif
public RequestBuilderImplementation(
+#if NET5_0_OR_GREATER
+ [DynamicallyAccessedMembers(
+ DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods
+ )]
+#endif
Type refitInterfaceType,
RefitSettings? refitSettings = null
)
@@ -65,7 +87,10 @@ static string GetLookupKeyForMethod(MethodInfo methodInfo)
}
void AddInterfaceHttpMethods(
- [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods)]Type interfaceType,
+#if NET5_0_OR_GREATER
+ [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)]
+#endif
+ Type interfaceType,
Dictionary> methods
)
{
@@ -175,6 +200,9 @@ RestMethodInfoInternal CloseGenericMethodIfNeeded(
return restMethodInfo;
}
+#if NET5_0_OR_GREATER
+ [RequiresUnreferencedCode("Building rest result delegates uses reflection over interface methods and DTOs. Ensure required members are preserved.")]
+#endif
public Func BuildRestResultFuncForMethod(
string methodName,
Type[]? parameterTypes = null,
@@ -1197,12 +1225,12 @@ var value in ParseEnumerableQueryParameterValue(
CollectionFormat.Ssv => " ",
CollectionFormat.Tsv => "\t",
CollectionFormat.Pipes => "|",
- _ => ","
+ _ => ","
};
// Missing a "default" clause was preventing the collection from serializing at all, as it was hitting "continue" thus causing an off-by-one error
var formattedValues = paramValues
- .Cast