Create a NativeAOT-compatible JsonRpc.AddLocalTargetObject method#1236
Merged
Create a NativeAOT-compatible JsonRpc.AddLocalTargetObject method#1236
Conversation
(it fails)
Classes can implement new interfaces without that being a binary breaking change. So we shouldn't start failing in those circumstances either. Interfaces on the other hand cannot add more base types without it being a binary breaking change, so that's ok to leave breaking if incomplete.
There was a problem hiding this comment.
Pull Request Overview
This PR introduces a new NativeAOT-compatible API for adding local RPC target objects to StreamJsonRpc. The primary purpose is to enable AOT-safe RPC target registration by providing explicit metadata handling instead of relying on dynamic reflection.
Key changes include:
- Introduction of
RpcTargetMetadataclass for explicit type metadata management - New
AddLocalRpcTargetoverload acceptingRpcTargetMetadatainstead of reflection-based types - Replacement of dynamic method discovery with pre-computed metadata structures
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/StreamJsonRpc/Reflection/RpcTargetMetadata.cs |
New core class providing AOT-safe metadata for RPC targets with interface/class analysis |
src/StreamJsonRpc/JsonRpc.cs |
Added new AddLocalRpcTarget overload accepting RpcTargetMetadata parameter |
src/StreamJsonRpc/Reflection/RpcTargetInfo.cs |
Refactored to use RpcTargetMetadata instead of dynamic type analysis |
test/StreamJsonRpc.Tests/RpcTargetMetadataTests.cs |
New test file validating metadata generation for interfaces and classes |
test/StreamJsonRpc.Tests/JsonRpcMethodAttributeTests.cs |
Updated tests to verify new behavior instead of expecting exceptions |
test/NativeAOTCompatibility.Test/Program.cs |
Updated to demonstrate new AOT-compatible API usage |
Comments suppressed due to low confidence (1)
test/StreamJsonRpc.Tests/JsonRpcTests.cs:1511
- This debugging code appears to be accidentally committed. The TraceSource configuration should be removed unless it's intentionally part of the test.
var rpc = new JsonRpc(streams.Item1, streams.Item2)
{
TraceSource = new TraceSource("Loopback", SourceLevels.Verbose)
{
Listeners = { new XunitTraceListener(this.Logger) },
},
};
murphymcquet-msft
approved these changes
Aug 6, 2025
This was referenced Jan 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This provides a NativeAOT safe API for adding local RPC target objects. It adds several API layers to maintain backward compatibility in a non-trim-safe way, then a nearly-as-friendly way to achieve trim/AOT safety but with trimming not being that good, then a slightly more low-level API that achieves great trimmability.
The low-level API requires you to explicitly code up a call to
Addfor each interface that a class or interface implements. That's a bit tedious, but doable. And in a subsequent change I'll write an interceptor so that this code is written for you automatically, allowing you to call the more friendly APIs and still be optimally trimmed.This is what NerdbankMessagePackFormatter (#1100) needs in order to support marshalable objects while remaining NativeAOT safe.