fix(csharp): make generichost oneOf constructors public#24341
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 40 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
|
The reasoning behind the current behavior is that if none of the properties have public setters, we infer that the model is only ever received from the server and never constructed by the caller, so an internal constructor is sufficient. However, this inference breaks down for oneOf wrapper types, which can be immutable by design yet still appear as request body inputs. The correct fix would be to determine constructor visibility based on whether the model actually appears as a request type in the spec, rather than inferring it from property mutability. The current PR uses {{>visibility}} uniformly, which makes constructors public on response-only models unnecessarily. |
Good point, thanks for raising it. I added an x-model-is-operation-input vendor extension that marks models reachable from operation parameters or request bodies, including nested and composed schemas. The Generic Host Mustache template uses this flag to make the oneOf constructor public by default. Otherwise, the constructor remains internal because client users do not need to construct response-only or unused models. |
Description
Fixes #23046.
The C# Generic Host template previously used model mutability (
x-model-is-mutable) to determine the visibility ofoneOfconstructors. However, mutability does not reliably indicate whether callers need to construct a model: an immutableoneOfwrapper may still be used as an API input.This change adds the codegen vendor extension
x-model-is-operation-input. It identifies models reachable from operation parameters or request bodies, including through:oneOf,allOf, andanyOf)additionalPropertiesNote: Read-only schema branches are excluded.
For a
oneOfconstructor, the template first checksx-model-is-operation-input:publicby default orinternalwhennonPublicApi=true.internal.Example
Given this OpenAPI document:
DynamicMetadataValueis reachable from the/uploadrequest body throughInitiateUploadRequest.dynamicMetadata.additionalProperties. Its constructors therefore use the configured visibility, which ispublicby default:ResponseOnlyValueis referenced only by the response. It is not an operation input, so its constructors remain internal:Compatibility note
Note that this change may alter the generated API surface for some oneOf models. Constructors that were previously public because the model was considered mutable will now be internal when the model is only used in responses or is not reachable from an operation input.
This is intentional, but consumers that manually construct response-only oneOf models may need to update their code.
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
@mandrean (2017/08) @shibayan (2020/02) @Blackclaws (2021/03) @lucamazzanti (2021/05) @iBicha (2023/07)
Summary by cubic
Make C# Generic Host
oneOfmodel constructors public only for operation inputs (request bodies and parameters). Fixes #23046 so immutableoneOfinputs are constructible across assemblies by default, while non-inputoneOfconstructors remain internal.{{>visibility}}for Generic HostoneOfconstructors and set topubliconly when the model is an operation input; otherwiseinternal. RespectsnonPublicApi=true.x-model-is-operation-input); updated template and codegen, added unit test and minimal OpenAPI fixture, and regenerated samples.Written for commit c312925. Summary will update on new commits.