feat(dotnet-sdk): Added support for generating a client interface#652
feat(dotnet-sdk): Added support for generating a client interface#652CharlieDigital wants to merge 1 commit intoopenfga:mainfrom
Conversation
|
|
WalkthroughThis PR updates the .NET SDK client generation by bumping the OpenAPI generator version from v6.4.0 to v7.15.0, updating the API reference commit, introducing a new IClient interface to abstract the SDK client, and adding two new model templates for write request operations (deletes and writes). Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull Request Overview
This PR adds interface support to the .NET SDK generator to enable mocking of the OpenFGA client in unit tests. The change addresses the issue where the OpenFgaClient class lacked an interface, making it difficult to create test doubles.
Key Changes:
- Created a new interface
IOpenFgaClientthat defines the public API contract - Updated the client class to implement this interface
- Upgraded OpenAPI Generator to v7.15.0 to support .NET 9
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
config/clients/dotnet/template/Client/IClient.mustache |
New template file that generates the IOpenFgaClient interface with all public client methods |
config/clients/dotnet/template/Client/Client.mustache |
Updated to implement the new IOpenFgaClient interface |
config/clients/dotnet/config.overrides.json |
Added configuration mapping for the new interface template file |
Makefile |
Updated OpenAPI generator version and API reference commit |
config/clients/dotnet/template/modelWriteRequestWrites.mustache |
New template file for WriteRequest writes model generation |
config/clients/dotnet/template/modelWriteRequestDeletes.mustache |
New template file for WriteRequest deletes model generation |
| {{>partial_header}} | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| {{#validatable}} | ||
| using System.ComponentModel.DataAnnotations; | ||
| {{/validatable}} | ||
| using System.Runtime.Serialization; | ||
| using System.Text.Json; | ||
| using System.Text.Json.Serialization; | ||
|
|
||
|
|
||
| namespace {{packageName}}.{{modelPackage}} | ||
| { | ||
| {{#models}} | ||
| {{#model}} | ||
| /// <summary> | ||
| /// {{description}}{{^description}}{{classname}}{{/description}} | ||
| /// </summary> | ||
| [DataContract(Name = "{{{name}}}")] | ||
| {{#discriminator}} | ||
| [JsonConverter(typeof(JsonSubtypes), "{{{discriminatorName}}}")] | ||
| {{#mappedModels}} | ||
| [JsonSubtypes.KnownSubType(typeof({{{modelName}}}), "{{{mappingName}}}")] | ||
| {{/mappedModels}} | ||
| {{/discriminator}} | ||
| public {{#isEnum}}{{^isArray}}{{>visibility}}{{/isArray}}{{/isEnum}}{{^isEnum}}partial {{/isEnum}}class {{{classname}}}{{#parent}} : {{{.}}}{{/parent}}{{^parent}} : IEquatable<{{classname}}>{{#validatable}}, IValidatableObject{{/validatable}}{{/parent}} | ||
| { | ||
| /// <summary> | ||
| /// Defines OnDuplicate behavior | ||
| /// </summary> | ||
| public enum OnDuplicateEnum | ||
| { | ||
| /// <summary> | ||
| /// Enum Error for value: error | ||
| /// </summary> | ||
| [EnumMember(Value = "error")] | ||
| Error = 1, | ||
|
|
||
| /// <summary> | ||
| /// Enum Ignore for value: ignore | ||
| /// </summary> | ||
| [EnumMember(Value = "ignore")] | ||
| Ignore = 2 | ||
| } | ||
|
|
||
| {{#vars}} | ||
| {{#isEnum}} | ||
| {{#allowableValues}} | ||
| /// <summary> | ||
| /// {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}} | ||
| /// </summary> | ||
| {{#description}} | ||
| /// <value>{{.}}</value> | ||
| {{/description}} | ||
| {{#isContainer}} | ||
| [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] | ||
| {{/isContainer}} | ||
| public {{#isArray}}{{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Dictionary{{/isMap}}<string, {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}>{{^isContainer}}{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isContainer}} {{name}} { get; set; } | ||
| {{^isContainer}} | ||
| {{>modelInnerEnum}} | ||
| {{/isContainer}} |
There was a problem hiding this comment.
[nitpick] The entire new file modelWriteRequestWrites.mustache appears to be a standard model template that duplicates the existing model generation logic with only a minor variation (OnDuplicate enum vs OnMissing enum). Consider using a shared base template with parameters to avoid maintaining duplicate code across multiple template files.
| {{>partial_header}} | |
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| {{#validatable}} | |
| using System.ComponentModel.DataAnnotations; | |
| {{/validatable}} | |
| using System.Runtime.Serialization; | |
| using System.Text.Json; | |
| using System.Text.Json.Serialization; | |
| namespace {{packageName}}.{{modelPackage}} | |
| { | |
| {{#models}} | |
| {{#model}} | |
| /// <summary> | |
| /// {{description}}{{^description}}{{classname}}{{/description}} | |
| /// </summary> | |
| [DataContract(Name = "{{{name}}}")] | |
| {{#discriminator}} | |
| [JsonConverter(typeof(JsonSubtypes), "{{{discriminatorName}}}")] | |
| {{#mappedModels}} | |
| [JsonSubtypes.KnownSubType(typeof({{{modelName}}}), "{{{mappingName}}}")] | |
| {{/mappedModels}} | |
| {{/discriminator}} | |
| public {{#isEnum}}{{^isArray}}{{>visibility}}{{/isArray}}{{/isEnum}}{{^isEnum}}partial {{/isEnum}}class {{{classname}}}{{#parent}} : {{{.}}}{{/parent}}{{^parent}} : IEquatable<{{classname}}>{{#validatable}}, IValidatableObject{{/validatable}}{{/parent}} | |
| { | |
| /// <summary> | |
| /// Defines OnDuplicate behavior | |
| /// </summary> | |
| public enum OnDuplicateEnum | |
| { | |
| /// <summary> | |
| /// Enum Error for value: error | |
| /// </summary> | |
| [EnumMember(Value = "error")] | |
| Error = 1, | |
| /// <summary> | |
| /// Enum Ignore for value: ignore | |
| /// </summary> | |
| [EnumMember(Value = "ignore")] | |
| Ignore = 2 | |
| } | |
| {{#vars}} | |
| {{#isEnum}} | |
| {{#allowableValues}} | |
| /// <summary> | |
| /// {{description}}{{^description}}Gets or Sets {{{name}}}{{/description}} | |
| /// </summary> | |
| {{#description}} | |
| /// <value>{{.}}</value> | |
| {{/description}} | |
| {{#isContainer}} | |
| [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] | |
| {{/isContainer}} | |
| public {{#isArray}}{{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Dictionary{{/isMap}}<string, {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}>{{^isContainer}}{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isContainer}} {{name}} { get; set; } | |
| {{^isContainer}} | |
| {{>modelInnerEnum}} | |
| {{/isContainer}} | |
| {{>modelWriteRequestWritesBase | |
| enumName="OnDuplicateEnum" | |
| enumSummary="Defines OnDuplicate behavior" | |
| enumValues=[ | |
| { "name": "Error", "value": "error", "summary": "Enum Error for value: error" }, | |
| { "name": "Ignore", "value": "ignore", "summary": "Enum Ignore for value: ignore" } | |
| ] | |
| }} | |
| {{/isContainer}} |
| {{>partial_header}} | ||
|
|
||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| {{#validatable}} | ||
| using System.ComponentModel.DataAnnotations; | ||
| {{/validatable}} | ||
| using System.Runtime.Serialization; | ||
| using System.Text.Json; | ||
| using System.Text.Json.Serialization; | ||
|
|
||
|
|
||
| namespace {{packageName}}.{{modelPackage}} |
There was a problem hiding this comment.
[nitpick] The entire new file modelWriteRequestDeletes.mustache appears to be a standard model template that duplicates the existing model generation logic with only a minor variation (OnMissing enum vs OnDuplicate enum). Consider using a shared base template with parameters to avoid maintaining duplicate code across multiple template files.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
config/clients/dotnet/config.overrides.json (1)
14-14: Bump packageVersion for the new public interface.Adding IOpenFgaClient is a feature; update the package version to signal the change and comply with versioning guidelines.
- "packageVersion": "0.7.0", + "packageVersion": "0.8.0",As per coding guidelines.
🧹 Nitpick comments (6)
Makefile (1)
35-36: Optional: pin golangci-lint image to a concrete version.Using latest-alpine is non-deterministic; consider a specific tag (e.g., v1.xx.x-alpine) to stabilize CI.
config/clients/dotnet/template/modelWriteRequestDeletes.mustache (2)
248-271: Guard against null AdditionalProperties in equality/hash.Public setter allows null assignment causing NREs.
Either coalesce in comparisons or initialize via property:
- public IDictionary<string, object> AdditionalProperties { get; set; } + public IDictionary<string, object> AdditionalProperties { get; set; } = new Dictionary<string, object>();And in Equals:
- && (this.AdditionalProperties.Count == input.AdditionalProperties.Count && this.AdditionalProperties.All(kv => input.AdditionalProperties.ContainsKey(kv.Key) && Equals(kv.Value, input.AdditionalProperties[kv.Key]))); + && ((this.AdditionalProperties ?? new Dictionary<string, object>()).Count + == (input.AdditionalProperties ?? new Dictionary<string, object>()).Count) + && (this.AdditionalProperties ?? new Dictionary<string, object>()).All(kv => + (input.AdditionalProperties ?? new Dictionary<string, object>()).ContainsKey(kv.Key) + && Equals(kv.Value, (input.AdditionalProperties ?? new Dictionary<string, object>())[kv.Key])));
170-172: Optional: prefer JsonElement for extension data.System.Text.Json commonly uses IDictionary<string, JsonElement> for extension data; reduces boxing and surprises on deserialization.
- public IDictionary<string, object> AdditionalProperties { get; set; } + public IDictionary<string, JsonElement> AdditionalProperties { get; set; }config/clients/dotnet/template/modelWriteRequestWrites.mustache (2)
248-271: Null-safety for AdditionalProperties in Equals/GetHashCode.Avoid NRE if consumer sets it to null.
Same coalescing/property-initializer approach as proposed in deletes template.
170-172: Optional: use JsonElement for extension data.Aligns with STJ defaults and avoids boxing.
- public IDictionary<string, object> AdditionalProperties { get; set; } + public IDictionary<string, JsonElement> AdditionalProperties { get; set; }config/clients/dotnet/template/Client/IClient.mustache (1)
37-189: Standardize comment formatting.The file uses inconsistent comment styles: some methods use
/**on a single line (lines 37, 43, 50, 55) while others use multi-line/** ... */format (lines 64+). For better consistency and maintainability, standardize to one format throughout.Consider using C# XML documentation comments (
///) instead, which would provide IntelliSense support:-/** - * ListStores - Get a paginated list of stores. - */ +/// <summary> +/// ListStores - Get a paginated list of stores. +/// </summary>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
Makefile(1 hunks)config/clients/dotnet/config.overrides.json(1 hunks)config/clients/dotnet/template/Client/Client.mustache(1 hunks)config/clients/dotnet/template/Client/IClient.mustache(1 hunks)config/clients/dotnet/template/modelWriteRequestDeletes.mustache(1 hunks)config/clients/dotnet/template/modelWriteRequestWrites.mustache(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
config/**/*.mustache
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Validate mustache syntax and variable references across all template files, including CHANGELOG.md.mustache
Files:
config/clients/dotnet/template/Client/Client.mustacheconfig/clients/dotnet/template/modelWriteRequestWrites.mustacheconfig/clients/dotnet/template/Client/IClient.mustacheconfig/clients/dotnet/template/modelWriteRequestDeletes.mustache
config/**/*.{json,mustache}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Never hardcode API keys or credentials in configuration or template files
Files:
config/clients/dotnet/template/Client/Client.mustacheconfig/clients/dotnet/config.overrides.jsonconfig/clients/dotnet/template/modelWriteRequestWrites.mustacheconfig/clients/dotnet/template/Client/IClient.mustacheconfig/clients/dotnet/template/modelWriteRequestDeletes.mustache
Makefile
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Makefile: Update OPEN_API_REF in the Makefile when targeting new OpenFGA API versions
Update Docker image tags in the Makefile when upgrading build tools
Use official, tagged Docker images for containerized builds
Files:
Makefile
config/clients/*/config.overrides.json
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
config/clients/*/config.overrides.json: Always update the packageVersion in each language-specific config.overrides.json when making version changes
Maintain FOSSA compliance notice IDs in each language’s config.overrides.json
Files:
config/clients/dotnet/config.overrides.json
config/{common/config.base.json,clients/*/config.overrides.json}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Ensure consistent versioning across base and language override configuration files to avoid version conflicts
Files:
config/clients/dotnet/config.overrides.json
🧠 Learnings (2)
📚 Learning: 2025-09-04T17:35:34.111Z
Learnt from: CR
PR: openfga/sdk-generator#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-04T17:35:34.111Z
Learning: Applies to Makefile : Update OPEN_API_REF in the Makefile when targeting new OpenFGA API versions
Applied to files:
Makefile
📚 Learning: 2025-09-04T17:35:34.111Z
Learnt from: CR
PR: openfga/sdk-generator#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-04T17:35:34.111Z
Learning: Applies to Makefile : Update Docker image tags in the Makefile when upgrading build tools
Applied to files:
Makefile
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-and-test-dotnet-sdk
🔇 Additional comments (10)
config/clients/dotnet/template/modelWriteRequestDeletes.mustache (1)
6-11: Ensure required usings are present for discriminators and validation.Attributes reference JsonSubtypes and Regex, but no using for JsonSubTypes/Regex is declared here.
If not provided by {{>partial_header}}, add:
{{#validatable}} using System.ComponentModel.DataAnnotations; +using System.Text.RegularExpressions; {{/validatable}} +using JsonSubTypes;Also applies to: 21-27
config/clients/dotnet/template/modelWriteRequestWrites.mustache (1)
6-11: Ensure usings for JsonSubtypes and Regex exist.Template uses JsonSubtypes and Regex without visible usings here.
Add if not in {{>partial_header}}:
{{#validatable}} using System.ComponentModel.DataAnnotations; +using System.Text.RegularExpressions; {{/validatable}} +using JsonSubTypes;Also applies to: 21-27
config/clients/dotnet/config.overrides.json (1)
69-72: Mapping for IClient looks correct.The new SupportingFiles entry will emit src/OpenFga.Sdk/Client/IClient.cs as intended.
Makefile (2)
5-5: Docker tag v7.15.0 verified to exist.The openapitools/openapi-generator-cli:v7.15.0 tag has been confirmed on Docker Hub and will not cause CI pull failures.
3-3: OPEN_API_REF bump verified.The spec file is reachable at the commit hash and exposes a valid OpenAPI 2.0 specification with version 1.x. No issues found.
config/clients/dotnet/template/Client/Client.mustache (1)
22-22: Signature parity verified — templates are correctly aligned.All public method and property signatures declared in
I{{appShortName}}Clientare properly implemented in{{appShortName}}Clientwith matching return types, parameters, and async contracts. Interface and implementation maintain complete parity across 18 methods and 2 properties. Private helper methods (e.g.,ProcessWriteChunksAsync,GetStoreId,MapOnDuplicateWrites) are correctly excluded from the interface. TheDispose()method properly implements theIDisposablecontract.config/clients/dotnet/template/Client/IClient.mustache (4)
1-21: LGTM!The header, imports, and namespace declarations are correctly structured. The mustache variable references (
{{>partial_header}}and{{packageName}}) follow proper syntax, and the conditional compilation directives appropriately handle framework-specific concerns.
23-31: LGTM!The properties correctly use nullable reference types and provide mutable access, which is appropriate for client configuration (store ID and authorization model ID can be set after client instantiation).
88-90: Verify nullable return type is intentional.The
ReadLatestAuthorizationModelmethod returnsTask<ReadAuthorizationModelResponse?>(nullable response). This differs from other methods likeReadAuthorizationModel(line 81) which returns non-nullableTask<ReadAuthorizationModelResponse>.Confirm this is intentional—likely indicating that the latest model may not exist. If so, ensure the implementing class and consumers handle the null case appropriately.
1-22: Mustache syntax is valid.The mustache template syntax is correct:
- Partial reference
{{>partial_header}}(line 1)- Variable references
{{packageName}}(lines 11-20) and{{appShortName}}(line 22)All mustache tags are properly formed with no unclosed or malformed constructs.
Based on coding guidelines.
| {{#isContainer}} | ||
| [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] | ||
| {{/isContainer}} | ||
| public {{#isArray}}{{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Dictionary{{/isMap}}<string, {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}>{{^isContainer}}{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isContainer}} {{name}} { get; set; } | ||
| {{^isContainer}} |
There was a problem hiding this comment.
Fix invalid generic type generation for enum containers.
Arrays shouldn’t get a Dictionary key parameter. Current template yields e.g. List<string, T>, which won’t compile.
Apply:
- public {{#isArray}}{{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Dictionary{{/isMap}}<string, {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}>{{^isContainer}}{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isContainer}} {{name}} { get; set; }
+ public {{#isArray}}
+ {{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}<{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}>
+ {{/isArray}}
+ {{#isMap}}
+ Dictionary<string, {{{
+ datatypeWithEnum
+ }}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}>
+ {{/isMap}}
+ {{^isContainer}}
+ {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}
+ {{/isContainer}} {{name}} { get; set; }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {{#isContainer}} | |
| [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] | |
| {{/isContainer}} | |
| public {{#isArray}}{{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Dictionary{{/isMap}}<string, {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}>{{^isContainer}}{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isContainer}} {{name}} { get; set; } | |
| {{^isContainer}} | |
| {{#isContainer}} | |
| [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] | |
| {{/isContainer}} | |
| public {{#isArray}} | |
| {{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}<{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}> | |
| {{/isArray}} | |
| {{#isMap}} | |
| Dictionary<string, {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}> | |
| {{/isMap}} | |
| {{^isContainer}} | |
| {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}} | |
| {{/isContainer}} {{name}} { get; set; } | |
| {{^isContainer}} |
🤖 Prompt for AI Agents
In config/clients/dotnet/template/modelWriteRequestDeletes.mustache lines 57-61,
the template incorrectly emits a Dictionary-style generic parameter for array
containers (producing e.g. List<string, T>), causing invalid C# generics; change
the conditional logic so Dictionary is emitted only when isMap is true and
arrays/collections emit a single generic type (List<T> or HashSet<T>) and maps
emit Dictionary<string, TValue>; ensure the mustache blocks nest/branch so the
key type ("string") is only included for isMap and the value type uses
{{{datatypeWithEnum}}} or {{{dataType}}} as currently used for non-container
types.
| {{#isContainer}} | ||
| [DataMember(Name="{{baseName}}", EmitDefaultValue={{emitDefaultValue}})] | ||
| {{/isContainer}} | ||
| public {{#isArray}}{{#uniqueItems}}HashSet{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Dictionary{{/isMap}}<string, {{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}>{{^isContainer}}{{{datatypeWithEnum}}}{{^datatypeWithEnum}}{{{dataType}}}{{/datatypeWithEnum}}{{/isContainer}} {{name}} { get; set; } | ||
| {{^isContainer}} |
There was a problem hiding this comment.
Fix invalid generic type generation for enum containers.
Same issue as deletes template: arrays currently render List<string, T>.
Apply the same conditional generic fix as suggested for the deletes template.
🤖 Prompt for AI Agents
In config/clients/dotnet/template/modelWriteRequestWrites.mustache around lines
57 to 61, the template is producing invalid generics like List<string, T> for
enum containers; change the conditional rendering so arrays render a single
generic (List<T> or HashSet<T> depending on uniqueItems) and maps render
Dictionary<string, T>, using {{{datatypeWithEnum}}} (falling back to
{{{dataType}}}) as the single type parameter; ensure the non-container branch
stays as just the type, and reuse the same conditional generic logic used in the
deletes template to avoid emitting two generic type arguments.
|
Going to redo this one. |
IOpenFgaClientfor theOpenFgaClient.Description
What problem is being solved?
It is currently not possible to mock the
OpenFgaClientin unit tests in .NET as its methods are not virtual and it does not provide an interface for mockingHow is it being solved?
This PR adds a template to generate an interface and adds the interface to the generated
OpenFgaClientwhich will allow unit tests to provide a mock using the interfaceIOpenFgaClientinstead.What changes are made to solve it?
config/clients/dotnet/template/Client/IClient.mustacheconfig/clients/dotnet/config.overrides.jsonto include the new.mustachefileconfig/clients/dotnet/template/Client/Client.mustacheto implement the interfaceMakefileto use latest OpenAPI generator which includes support for .NET 9References
Review Checklist
mainSummary by CodeRabbit
New Features
Chores