Skip to content

feat: add for support AOT request routing#2182

Closed
TimothyMakkison wants to merge 19 commits into
reactiveui:mainfrom
TimothyMakkison:sot_route
Closed

feat: add for support AOT request routing#2182
TimothyMakkison wants to merge 19 commits into
reactiveui:mainfrom
TimothyMakkison:sot_route

Conversation

@TimothyMakkison

@TimothyMakkison TimothyMakkison commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Adds AOT support for request routing

  • Supports standard parameter routing
  • Supports object property routing
  • Emits an exception if round trip parameter is used with the wrong type
  • Emits a guard check if an unmatched route parameter is found
  • Supports ICustomAttributeProvider by caching ParameterInfo and PropertyInfo lookups in a ConcurrentDictionary
    • Note that it would be possible to calculate these values once when a class is first constructed and store them as static fields in the generated class, I chose this solution as it is easier from a code gen perspective. Note that fields may be faster than a ConcurrentDictionary
  • Parsing logic is based upon RestMethodInfoInternal and emitting logic is based upon RequestBuilderImplementation.RequestBuilding
  • Generated code either uses current solution or uses a series of ValueStringBuilder calls
  • Should be fairly easy to add query support after

Haven't added tests or cleaned up yet, would like to hear feed back before doing anything more.

  • ValueStringbuilder is currently public, I suspect it could be emitted once within internal partial class Generated
[Get("/{unmatched}/{id}/hello/{val.Value}/{**round}")]
public Task<ApiResponse<List<User>>> GetUsers(MyData val, int id, string round);

var refitSettings = _settings;
var valueStringBuilder = new global::Refit.ValueStringBuilder(stackalloc char[256]);
valueStringBuilder.Append("/");
global::Refit.GeneratedRequestRunner.UnmatchedRouteParameterGuard(refitSettings, "URL /{unmatched}/{id}/hello/{val.Value} has parameter unmatched, but no method parameter matches");
valueStringBuilder.Append("{unmatched}");
valueStringBuilder.Append("/");
global::Refit.GeneratedRequestRunner.AddStandardParameter(ref valueStringBuilder, id, false, refitSettings, typeof(global::Refit.Benchmarks.ITest), "GetUsers", "id");
valueStringBuilder.Append("/hello/");
global::Refit.GeneratedRequestRunner.AppendObjectPropertyFragment(ref valueStringBuilder, val.Value, refitSettings, typeof(global::Refit.Benchmarks.ITest.MyData), "Value");
valueStringBuilder.Append("/");
global::Refit.GeneratedRequestRunner.AddStandardParameter(ref valueStringBuilder, round, true, refitSettings, typeof(global::Refit.Benchmarks.ITest), "GetUsers", "round");


var refitRequest = new global::System.Net.Http.HttpRequestMessage(global::System.Net.Http.HttpMethod.Get, global::Refit.GeneratedRequestRunner.BuildRelativeUri(this.Client, valueStringBuilder.ToString(), refitSettings.UrlResolution));
               

Note that the above code could probably be simplified with CalledMemberName and nameof

@TimothyMakkison TimothyMakkison changed the title feat: Add support AOT request routing feat: Add for support AOT request routing Jun 29, 2026
@TimothyMakkison TimothyMakkison marked this pull request as draft June 29, 2026 20:14
@TimothyMakkison TimothyMakkison changed the title feat: Add for support AOT request routing feat: add for support AOT request routing Jun 29, 2026
@TimothyMakkison

Copy link
Copy Markdown
Collaborator Author

Tests

Need to look into writing more tests, especially generated tests to ensure that exception generation and the unmatched route are emitted.

Failing tests

  • Looking at the failing tests most of them are from [Bug]: derived types erroneously add additional query parameters. #1882, which were tests meant to verify that the "broken" behaviour is till present.
  • GeneratedSourcesCompileWithCSharp73Baseline fails as stackalloc expressions aren't supported in that version of C#, TBH if this is an issue I can have the emitter check the language version and either emit new or stackalloc and get identical results.
  • Tests are failing due reflection ambiguity when a method has multiple overloads, looking at my notes from Aot gen #1965 it's kind of tricky to do this in a performant way without adding a bunch of complexity or doing a lot of work when the generated class is first cctor'd

Tempted to try and add Query support in the same PR, happy to make a follow up Pr otherwise.

@glennawatson

Copy link
Copy Markdown
Contributor

Hows this related to the work in #2174

@ChrisPulman

Copy link
Copy Markdown
Member

@TimothyMakkison check the Slack messages :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants