-
Notifications
You must be signed in to change notification settings - Fork 2k
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
[CodeGen] Always specify grain extension interface for grain extension calls #9009
Conversation
…on interface, not the original interface
I added another commit: we should always use explicit interface implementations when generating proxies. this lets us correctly handle ambiguities we couldn't correctly handle before. The code is also simpler. |
7d3836d
to
434aae2
Compare
Is the internal access also part of this PR? I get a public type derived from TaskRequest.. That would resolve the issue with internal payload classes (and internal interface methods). |
@alrz currently, we only consider the visibility of the interface itself, but we could take a change to also consider the visibility of the method, if that's valid, and generate the invoker using the least visible of the two. See InvokableGenerator.cs:49-55 |
That would definitely work but I'm wondering if there's any reason at all to make it anything other than |
@alrz |
In that case, wouldn't we generate the whole thing inside the "current" project including the types related to the external interface? that is, the client wouldn't have any knowledge if the referenced interface from another assembly is indeed a grain. If that's correct I think file-scoped types should work just fine? |
Sorry I think you're saying the interface AND the grain impl are sourced from outside, in which case we're going to lookup invokers from the referenced assembly. I don't know where this happens or whether or not we use literal C# to do that but afaik Activator is able to create types no matter where they are declared. |
The Grain impl isn't an issue here. The scenario I'm talking about is when you have: // in Asm A
interface IMyDerived : IMyBase
{
... methods ...
}
// in Asm B
interface IMyBase : IGrain
{
... methods ...
} We need to generate The way it works now, we only generate the |
In #8749, we changed how we generate invokers (essentially, closure classes which represent grain method invocations) so that we only generate one invoker for each original method definition. That was in response to an issue uncovered by one of the analyzers which @ledjon-behluli added: https://discord.com/channels/333727978460676096/922948121619751012/1179628138490232923, where it was previously impossible to add aliases to some types.
Unfortunately, that caused an issue, which @oising hit: for grain extensions, we need to know which extension interface to fetch from the grain so that we can execute the right method against it.
The following code snippet corresponds to the grain extension test interface added in this PR.
Notice that the
target
field is typed based on the original method definition's interface, whileSetTarget
uses the grain extension's interface. That is the desired outcome, ensuring we get the right extension while also calling the correct method overload.Microsoft Reviewers: Open in CodeFlow