From 3bb8f203d6f40a364bed874b5847afeb1aba7eae Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 13 Jun 2025 15:27:09 -0500 Subject: [PATCH] Cut ProxyGeneration out if dynamic code isn't supported Since ProxyGeneration always generates IL code using RefEmit, it will never work in native AOT'd apps. But currently it is still brought into the app because RpcMarshalableConverterFactory (used by SystemTextJsonFormatter by default) eventually calls into it. To remove references to Newtonsoft.Json, we can cut this off in AOT'd apps by checking if dynamic code isn't supported and throw an exception. This will allow ProxyGeneration to be trimmed from the final app. This isn't a perfect fix, but instead a compromise. The best fix would be to make RpcMarshalableConverterFactory work correctly in AOT'd apps. --- src/StreamJsonRpc/JsonRpc.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/StreamJsonRpc/JsonRpc.cs b/src/StreamJsonRpc/JsonRpc.cs index 230c3c0a0..add25ef0b 100644 --- a/src/StreamJsonRpc/JsonRpc.cs +++ b/src/StreamJsonRpc/JsonRpc.cs @@ -7,6 +7,7 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; +using System.Runtime.CompilerServices; using Microsoft.VisualStudio.Threading; using Newtonsoft.Json; using StreamJsonRpc.Protocol; @@ -2775,6 +2776,13 @@ private T CreateProxy(ReadOnlySpan additionalContractInterfaces, ReadOn [RequiresDynamicCode(RuntimeReasons.RefEmit), RequiresUnreferencedCode(RuntimeReasons.RefEmit)] private IJsonRpcClientProxyInternal CreateProxy(Type contractInterface, ReadOnlySpan additionalContractInterfaces, ReadOnlySpan<(Type Type, int Code)> implementedOptionalInterfaces, JsonRpcProxyOptions? options, long? marshaledObjectHandle) { +#if !NETSTANDARD2_0 + if (!RuntimeFeature.IsDynamicCodeSupported) + { + throw new NotSupportedException("CreateProxy is not supported if dynamic code is not supported."); + } +#endif + TypeInfo proxyType = ProxyGeneration.Get(contractInterface, additionalContractInterfaces, implementedOptionalInterfaces); return (IJsonRpcClientProxyInternal)Activator.CreateInstance( proxyType.AsType(),