C# Protobuf-net.Grpc服务合同继承

C# Protobuf-net.Grpc服务合同继承,c#,asp.net-core,grpc,protobuf-net,C#,Asp.net Core,Grpc,Protobuf Net,我正在将一个应用程序从.Net FW升级到.Net Core。还将WCF服务升级为gRPC服务。我们决定使用protobuf-net.Grpc 我们对服务契约使用多级继承 [ServiceContract] public interface IBaseServiceContract<TDataModel> where TDataModel : DataModelObject { } [ServiceContract] public interface ICRUDLServiceCo

我正在将一个应用程序从.Net FW升级到.Net Core。还将WCF服务升级为gRPC服务。我们决定使用protobuf-net.Grpc

我们对服务契约使用多级继承

[ServiceContract]
public interface IBaseServiceContract<TDataModel> where TDataModel : DataModelObject
{
}

[ServiceContract]
public interface ICRUDLServiceContract<TDataModel> : IBaseServiceContract<TDataModel> where TDataModel : DataModelObject
{
    Task<Response<TDataModel>> Create(Request<TDataModel> request);
    Task<Response<TDataModel>> Read(Request<TDataModel> request);
    Task<VoidResponse> Update(Request<TDataModel> request);
    Task<VoidResponse> Delete(Request<TDataModel> request);
    Task<Response<DataResult<TDataModel>>> List(Request<DataSourceQuery> request);
    Task<Response<IEnumerable<TDataModel>>> ListAll();
}
然后我尝试从基本接口中删除
[ServiceContract]

warn: Grpc.AspNetCore.Server.Model.Internal.ServiceRouteBuilder[3]
No gRPC methods discovered for OverBase.Services.Program.ProductService.
基本接口中的方法已从服务中消失


在protobuf net.Grpc中有没有一种使用基本接口方法的方法?

在github上报告这将是一个很好的bug。问题在于契约绑定器不会展开泛型,因此您最终会使用.NET泛型占位符(但内部API不同)在相同的名称上提供多个服务:

从长远来看,我们应该修复图书馆。使用属性来解决这一问题并不容易,因为属性不是按-
t
,但是:我们可以编写自己的活页夹:

//注意:这也可以识别一些已知的接口
类MyServiceBinder:ServiceBinder
{
受保护的重写字符串GetDefaultName(类型contractType)
{
var val=base.GetDefaultName(contractType);
if(val.EndsWith(“`1”)&&contractType.IsGenericType)
{//用IFoo`TheThing替换IFoo`1
var args=contractType.GetGenericArguments();
如果(args.Length==1)
{
val=val.Substring(0,val.Length-1)+args[0]。名称;
}
}
返回val;
}
}
对于ASP.NET,我们向DI注册:

services.AddSingleton(BinderConfiguration.Create(binder:newmyServiceBinder());
对于客户端,您可以将其传递给客户端创建者:

static readonly ClientFactory s\u ClientFactory=ClientFactory.Create(
创建(绑定器:newmyservicebinder());
// ...
var calculator=http.CreateGrpcService(s_ClientFactory);
其结果是,我们必须:

IFoo`X/Method
IFoo`Y/Method

显然,你可以自由地建议不同的模式!gRPC不太关心它们是什么。

您可以启用调试级日志记录吗?绑定时,您应该看到所有映射—例如
添加了gRPC方法“Subscribe”到服务“MegaCorp.TimeService”。方法类型:'ServerStreaming',路由模式:'/MegaCorp.TimeService/Subscribe.
-我可以假设它们在这里冲突吗?大概我们想要的是在per-T级别定义子类型路由的某种方法?意思:这里的问题是
`1
。我们可以很容易地解决这个问题,比如
CRUDLServiceContract`Foo
CRUDLServiceContract`Bar
之类的?它需要一个相当小的代码改变。具体来说,这个方法应该考虑泛型:FY:长期修复现在是GITHUB:
...
endpoints.MapGrpcService<ProductService>();
endpoints.MapGrpcService<TitleService>();
...
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 POST https://localhost:7001/OverBase.Core.Contract.CRUDLServiceContract`1/List application/grpc -
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches:

gRPC - /OverBase.Core.Contract.CRUDLServiceContract`1/List
gRPC - /OverBase.Core.Contract.CRUDLServiceContract`1/List
warn: Grpc.AspNetCore.Server.Model.Internal.ServiceRouteBuilder[3]
No gRPC methods discovered for OverBase.Services.Program.ProductService.
IFoo`1/Method
IFoo`1/Method
IFoo`X/Method
IFoo`Y/Method