feat: generate request construction to avoid reflection pipeline#2150
Merged
Conversation
…t targets - Removed `refit.targets` as it is no longer needed with updated source generators. - Added new generator options for disabling source generation and enabling request building. - Updated tests and snapshots to reflect new default behaviors with generated request construction.
- Added generated interface stub snapshots for various test scenarios, including `IGitHubApiDisposable`, `INestedGitHubApi`, and `IServiceWithoutNamespace`. - Ensures proper test coverage of generated output scenarios.
… support - Improved `PackageDescription` and `PackageTags` for all projects to better reflect functionality and compatibility. - Updated README to align with modern .NET platforms and features (`HttpClientFactory`, trimming, AOT). - Added repository metadata and centralized version management settings.
…rocessing - Introduced `RequestExecutionHelpers` to encapsulate shared logic for request execution and response handling. - Added a new `RequestExecutionOptions` struct to configure request processing behavior. -
- Added new test cases for `ApiException`, `ValidationApiException`, `ApiResponse<T>`, and `PooledBufferWriter` classes. - Removed legacy configuration files: `filelist.txt` and `signclient.json`.
…pdate stream exception handling - Replaced repetitive `ArgumentNullException` checks with `ArgumentExceptionHelper.ThrowIfNull` for improved code clarity. - Updated stream exception handling by removing unnecessary catches for `OperationCanceledException`. - Annotated certain methods with `[ExcludeFromCodeCoverage]` to improve test coverage tracking. - Removed `AllowUnsafeBlocks` from project files for safer code compliance. - Added new and modified tests to verify behavior consistency, including enhanced coverage for API response and exception scenarios.
ChrisPulman
approved these changes
Jun 20, 2026
- Introduced `ArgumentExceptionHelper` and `ArgumentOutOfRangeExceptionHelper` classes to add polyfills for argument validation on older target frameworks. - Included `CallerArgumentExpressionAttribute` and `NotNullAttribute` polyfills for improved compatibility with legacy frameworks. - Added unit tests to validate `BodyAttribute`, `AttachmentNameAttribute`, and `DefaultFormUrlEncodedParameterFormatter` behaviors and scenarios.
…rocessing - Introduced `Emitter.Helpers.cs`, `Parser.Helpers.cs`, and `Parser.Request.Helpers.cs` to modularize and centralize helper functions for generated stubs and request handling logic. - Moved query and header-handling logic to `RequestBuilderImplementation.QueryAndHeaders.Helpers.cs` for improved organization and maintainability. - Refactored existing logic to leverage shared helpers, reducing redundancy and increasing code clarity.
|
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.



What kind of change does this PR introduce?
Feature
What is the new behavior?
This PR adds the generation 2 request-building path for Refit source-generated clients. When
RefitGeneratedRequestBuildingis enabled, eligible generated methods no longer route through the reflective runtime request-builder path. Instead, the generator emits the request construction directly into the generated client method:HttpRequestMessageinstances in generated code[Header]parameters, and[HeaderCollection]handling[Body]serialization setup and buffering/streaming behavior[Property]parameters and interface property values into request options/propertiesGeneratedRequestRunnerruntime helper instead of building an invocation delegate throughBuildRestResultFuncForMethodThe opt-in keeps the existing reflective path as the default and preserves fallback behavior for request shapes that are not safe to generate inline yet. The tests explicitly assert both sides: switch-off output still uses the reflective builder, while switch-on output avoids it for supported methods.
The generator itself is reworked around the new request model used by this path:
The runtime receives the support surface needed by the generated code:
GeneratedRequestRunneras the shared runtime implementation for generated request sending, body content creation, header application, configured request options, and typed request propertiesRefitGeneratedRequestBuildingas a compiler-visible MSBuild property with a default offalseHashCodeand adds framework polyfills forHashCode,Index, andRangeIndex.GetOffsetThe test layout is also updated:
Refit.TestsintoRefit.GeneratorTestsWhat is the current behavior?
Generated Refit clients currently call into
BuildRestResultFuncForMethodand pass anobject[]argument array to the runtime request builder. That path depends on runtime method metadata lookup and request-building infrastructure even when the generator has enough information to emit the request construction directly.The source generator implementation is also still wired through the older shared-project/projitems setup, and source-generation tests are mixed into the main runtime test project.
What might this PR break?
The generated request-building path is opt-in and defaults to off, so existing generated clients should continue using the current reflective request-builder path unless a consumer enables
RefitGeneratedRequestBuilding.The PR does add a new public-but-editor-hidden runtime helper surface for generated code and updates public API baselines accordingly. Generated source snapshots change because the generator implementation and emitted helper wiring changed.
Checklist
mainbranchAdditional information
Validation run locally:
dotnet build src/Refit.slnx -c Release -v:minimal --no-restoredotnet build src/tests/Refit.GeneratorTests/Refit.GeneratorTests.csproj -c Release -f net8.0 -v:minimal --no-restoresrc/tests/Refit.GeneratorTests/bin/Release/net8.0/Refit.GeneratorTestssrc/tests/Refit.Tests/bin/Release/net8.0/Refit.Tests