-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[C#] API model name conflicts with namespace #4475
Comments
Thanks for raising this @peterwurzinger The generator does make attempts at type disambiguation in various scenarios to use the fully qualified name of the model/type. It may be that this is not a scenario captured by the current logic here. And we need to capture for a case where the model name matches the namespace name.
Any chance you'd be willing to share an openApi description to help understand better the scenario that is not captured? |
Hey there @andrueastman, thanks for investigating Sure, absolutely. I created a repository at https://github.com/peterwurzinger/KiotaRepro that should contain a minimal reproduction of that issue. I used the PayPal subscriptions API available at https://github.com/paypal/paypal-rest-api-specifications/blob/main/openapi/billing_subscriptions_v1.json, and since it's a public API I guess they wouldn't be too pissed about being used in a bug repro :) The Kiota command used for creating the client was dotnet kiota generate -l CSharp -c PayPalSubscriptionsClient -n KiotaRepro.Subscriptions.PayPal.Client -d https://raw.githubusercontent.com/paypal/paypal-rest-api-specifications/main/openapi/billing_subscriptions_v1.json -o ./Client |
I can get the repro to work by applying the following change here. -namespace KiotaRepro.Subscription.PayPal;
+namespace KiotaRepro.Subscriptions.PayPal; I believe it's only a matter of misalignment between how the dotnet project was initialized and the namespace argument passed to kiota. Can you confirm please? |
Hey @baywet Obviously renaming application namespaces to not contain names of the generated client models would resolve the problem, but that's not really something I would consider doing in an application larger than the one shown in the repro. |
Thanks for the additional information. Let us know if you have further questions/concerns. |
Yes, I'm aware that, just as renaming them, removing entire namespaces from the existing code would eliminate any type disambiguation with those in the generated code. I would argue, that they exist for a specific reason and not just for fun (or a repro), and in the best of cases people spend quite some time in naming them properly to reduce cognitive load when working within complex application ecosystems. In my naive view of how Kiota generates C# clients, those specific problems could be avoided by using the FQN when referencing generated types. So if Kiota e.g. replaced this expression with -<Subscription?>
+<KiotaRepro.Application.Features.Payment.Providers.PayPal.Client.Subscriptions.Models.Subscription?> then the application would compile properly as well. (I know that in fact it would not, since there are 4 occurences of this compiler error, but they would be resolved using the same fix.) The thing is, I obviously don't have any deeper knowledge about how Kiota manages the abstract representation of APIs, or how the C# client builder emits the requested code, but I don't see where using the FQN instead of just the generated types name would require deeper integration work in diverse compiler technologies. |
Thanks for articulating this further. |
As far as I know using the FQN everywhere is quite similar to the behavior of NSwag, the current default tooling for generating Connected Services clients in VS. There are some conceptual differences, as everything is being emitted into one file and one namespace, therefore avoiding some collisions in advance, but those clients contain constructs as e.g. private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings; or var headers_ = System.Linq.Enumerable.ToDictionary(response_.Headers, h_ => h_.Key, h_ => h_.Value); I would agree that the readability is somewhat more limited, yes. But even if I'm just a single reference, I couldn't remember needing to read the code of a generated service client for other purposes than debugging them every now and then. |
Sorry, I realized that I never came back to that last answer. The last few weeks have been a bit hectic to say the least. |
@baywet Sorry, last week was a bit rough. Yeah, sure, I started looking into it. From what I could see in the codebase, there are some issues that I want to point out:
So the overall surface of necessary changes would be quite big with only little improvement to the codebase after all, and potentially opening the door for bugs to be introduced within those changes. Speaking of tests: I think there would be a need for robust regression tests, that ensure that the generated code uses FQN for type references everywhere - even for code that is committed afterwards. I just can't see how these could be implemented with reasonable effort That a ll being said, in my opinion it would be a good idea to discuss a compromise, that would still resolve the raised issue, but without introducing huge changes. My proposal would be to use the FQN only for types generated by Kiota. That would resolve the issue, leaving edge cases for openApi schema names like |
I'm a bit disappointed that #4751 was merged. One thing that I like in kiota is the tidy code which is generated, exactly like if it was written manually (except for the conditional compilation around nullable types, which is why I keep rebasing #3945 onto the main branch). The type can't use the same name as the namespace is annoying but I always prefer to solve it by tweaking the namespace to avoid collisions. I just tried to generate a new API client with this change merged and it's becoming pretty ugly. 🙁 |
I was updating my generated client this morning with the latest kiota bits and came to a similar conclusion as @0xced. The code now looks ugly. At first, i thought there was a bug introduced somewhere and went looking for changes. Examples taken from Graph client (this change causes nearly all files to change): |
Thanks for the feedback. Continuing the discussion on #4796 |
When generating a C# client for an API, where a model has the same name as a part of its namespace , the compiler would raise CS0118 ("'XY is a namespace but is used like a type'") on various locations in the generated code.
E.g.
Response model "Subscription" generated as part of an API client in namespace "Whatever.Application.Subscription.Client"
As a workaround one can use the fully qualified type name to correct the generated code. That has the drawback that it would get overwritten permanently when the clients are being regenerated though.
Kiota Version 1.13.0
The text was updated successfully, but these errors were encountered: