diff --git a/src/Orleans.CodeGenerator/Model/ProxyInterfaceDescription.cs b/src/Orleans.CodeGenerator/Model/ProxyInterfaceDescription.cs index 05ef82e6c9..9c6c7600d5 100644 --- a/src/Orleans.CodeGenerator/Model/ProxyInterfaceDescription.cs +++ b/src/Orleans.CodeGenerator/Model/ProxyInterfaceDescription.cs @@ -79,6 +79,14 @@ private List GetMethods() { foreach (var method in iface.GetDeclaredInstanceMembers()) { + if (method.MethodKind == MethodKind.ExplicitInterfaceImplementation) + { + // Explicit implementations can be ignored when generating a proxy. + // Proxies must implement every method explicitly to ensure faithful reproduction of the interface behavior. + // At the calling side, the explicit implementation will be called if it was not overridden by a derived type. + continue; + } + var methodDescription = CodeGenerator.GetProxyMethodDescription(InterfaceType, method: method); result.Add(methodDescription); } diff --git a/test/DefaultCluster.Tests/CodeGenTests/IRuntimeCodeGenGrain.cs b/test/DefaultCluster.Tests/CodeGenTests/IRuntimeCodeGenGrain.cs index 5c490c6afe..bc3da0c948 100644 --- a/test/DefaultCluster.Tests/CodeGenTests/IRuntimeCodeGenGrain.cs +++ b/test/DefaultCluster.Tests/CodeGenTests/IRuntimeCodeGenGrain.cs @@ -8,6 +8,28 @@ namespace Tester.CodeGenTests using Orleans; using Orleans.Providers; + public interface ISomeInterface + { + Task M(T arg); + } + + public interface IBase : ISomeInterface; + + public interface IDerived : IBase, ISomeInterface + { + Task ISomeInterface.M(object obj) => M(obj); + } + + public interface ISomeGrainWithExplicitImplementation : IDerived, IGrainWithGuidKey; + + public class SomeGrain : Grain, ISomeGrainWithExplicitImplementation + { + public Task M(string arg) + { + throw new NotImplementedException(); + } + } + public interface IGrainWithGenericMethods : IGrainWithGuidKey { Task GetTypesExplicit();