/// <summary> /// 生成Grpc方法(CodeFirst方式,用于生成BaseService) /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="srv"></param> /// <param name="methodName"></param> /// <param name="package"></param> /// <param name="srvName"></param> /// <param name="mType"></param> /// <returns></returns> public static Method <TRequest, TResponse> BuildMethod <TRequest, TResponse>(this IGrpcService srv, string methodName, string package = null, string srvName = null, MethodType mType = MethodType.Unary) { var serviceName = srvName ?? GrpcExtensionsOptions.Instance.GlobalService ?? srv.GetType().Name; var pkg = package ?? GrpcExtensionsOptions.Instance.GlobalPackage; if (!string.IsNullOrWhiteSpace(pkg)) { serviceName = $"{pkg}.{serviceName}"; } #region 为生成proto收集信息 if (!(srv is IGrpcBaseService) || GrpcExtensionsOptions.Instance.GenBaseServiceProtoEnable) { ProtoInfo.Methods.Add(new ProtoMethodInfo { ServiceName = serviceName, MethodName = methodName, RequestName = typeof(TRequest).Name, ResponseName = typeof(TResponse).Name, MethodType = mType }); ProtoGenerator.AddProto <TRequest>(typeof(TRequest).Name); ProtoGenerator.AddProto <TResponse>(typeof(TResponse).Name); } #endregion var request = Marshallers.Create <TRequest>((arg) => ProtobufExtensions.Serialize <TRequest>(arg), data => ProtobufExtensions.Deserialize <TRequest>(data)); var response = Marshallers.Create <TResponse>((arg) => ProtobufExtensions.Serialize <TResponse>(arg), data => ProtobufExtensions.Deserialize <TResponse>(data)); return(new Method <TRequest, TResponse>(mType, serviceName, methodName, request, response)); }
/// <summary> /// 生成Grpc方法(CodeFirst方式,用于生成BaseService) /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="srv"></param> /// <param name="methodName"></param> /// <param name="package"></param> /// <param name="srvName"></param> /// <param name="mType"></param> /// <returns></returns> public static Method <TRequest, TResponse> BuildMethod <TRequest, TResponse>(this IGrpcService srv, string methodName, string package = null, string srvName = null, MethodType mType = MethodType.Unary) { var serviceName = srvName ?? GrpcExtensionsOptions.Instance.GlobalService ?? srv.GetType().Name; var pkg = package ?? GrpcExtensionsOptions.Instance.GlobalPackage; if (!string.IsNullOrWhiteSpace(pkg)) { serviceName = $"{pkg}.{serviceName}"; } var request = Marshallers.Create <TRequest>((arg) => ProtobufExtensions.Serialize <TRequest>(arg), data => ProtobufExtensions.Deserialize <TRequest>(data)); var response = Marshallers.Create <TResponse>((arg) => ProtobufExtensions.Serialize <TResponse>(arg), data => ProtobufExtensions.Deserialize <TResponse>(data)); return(new Method <TRequest, TResponse>(mType, serviceName, methodName, request, response)); }
/// <summary> /// 生成Grpc方法(CodeFirst方式) /// </summary> /// <typeparam name="TRequest"></typeparam> /// <typeparam name="TResponse"></typeparam> /// <param name="srv"></param> /// <param name="methodName"></param> /// <param name="package"></param> /// <param name="srvName"></param> /// <param name="mType"></param> /// <returns></returns> public static Method <TRequest, TResponse> BuildMethod <TRequest, TResponse>(this IGrpcService srv, string methodName, string package = null, string srvName = null, MethodType mType = MethodType.Unary) { var serviceName = srvName ?? GrpcExtensionsOptions.Instance.GlobalService ?? (srv.GetType().FullName.StartsWith("Castle.Proxies.") ? srv.GetType().Name.Substring(0, srv.GetType().Name.Length - 5) : srv.GetType().Name); var pkg = package ?? GrpcExtensionsOptions.Instance.GlobalPackage; if (!string.IsNullOrWhiteSpace(pkg)) { serviceName = $"{pkg}.{serviceName}"; } #region 为生成proto收集信息 if (!(srv is IGrpcBaseService) || GrpcExtensionsOptions.Instance.GenBaseServiceProtoEnable) { var protoMethodInfo = new ProtoMethodInfo { ServiceName = serviceName, MethodName = methodName, RequestName = typeof(TRequest).Name, ResponseName = typeof(TResponse).Name, MethodType = mType }; if (typeof(TRequest).IsGenericType) { protoMethodInfo.RequestName = $"{protoMethodInfo.RequestName.Substring(0, protoMethodInfo.RequestName.IndexOf('`'))}_{typeof(TRequest).GetGenericArguments()[0].Name}"; } if (typeof(TResponse).IsGenericType) { protoMethodInfo.ResponseName = $"{protoMethodInfo.ResponseName.Substring(0, protoMethodInfo.ResponseName.IndexOf('`'))}_{typeof(TResponse).GetGenericArguments()[0].Name}"; } ProtoInfo.Methods.Add(protoMethodInfo); ProtoGenerator.AddProto <TRequest>(protoMethodInfo.RequestName); ProtoGenerator.AddProto <TResponse>(protoMethodInfo.ResponseName); } #endregion var request = Marshallers.Create <TRequest>((arg) => ProtobufExtensions.Serialize <TRequest>(arg), data => ProtobufExtensions.Deserialize <TRequest>(data)); var response = Marshallers.Create <TResponse>((arg) => ProtobufExtensions.Serialize <TResponse>(arg), data => ProtobufExtensions.Deserialize <TResponse>(data)); return(new Method <TRequest, TResponse>(mType, serviceName, methodName, request, response)); }
/// <summary> /// 自动注册服务方法 /// </summary> /// <param name="srv"></param> /// <param name="builder"></param> /// <param name="package"></param> /// <param name="serviceName"></param> public static void AutoRegisterMethod(IGrpcService srv, ServerServiceDefinition.Builder builder, string package = null, string serviceName = null) { var methods = srv.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); foreach (var method in methods) { if (!method.ReturnType.Name.StartsWith("Task")) { continue; } var parameters = method.GetParameters(); if (parameters[parameters.Length - 1].ParameterType != typeof(ServerCallContext) || method.CustomAttributes.Any(x => x.AttributeType == typeof(NotGrpcMethodAttribute))) { continue; } Type inputType = parameters[0].ParameterType; Type inputType2 = parameters[1].ParameterType; Type outputType = method.ReturnType.IsGenericType ? method.ReturnType.GenericTypeArguments[0] : method.ReturnType; var addMethod = unaryAddMethod; var serverMethodType = typeof(UnaryServerMethod <,>); var methodType = MethodType.Unary; var reallyInputType = inputType; var reallyOutputType = outputType; //非一元方法 if ((inputType.IsGenericType || inputType2.IsGenericType)) { if (inputType.Name == "IAsyncStreamReader`1") { reallyInputType = inputType.GenericTypeArguments[0]; if (inputType2.Name == "IServerStreamWriter`1")//双向流 { addMethod = duplexStreamingAddMethod; methodType = MethodType.DuplexStreaming; serverMethodType = typeof(DuplexStreamingServerMethod <,>); reallyOutputType = inputType2.GenericTypeArguments[0]; } else//客户端流 { addMethod = clientStreamingAddMethod; methodType = MethodType.ClientStreaming; serverMethodType = typeof(ClientStreamingServerMethod <,>); } } else if (inputType2.Name == "IServerStreamWriter`1")//服务端流 { addMethod = serverStreamingAddMethod; methodType = MethodType.ServerStreaming; serverMethodType = typeof(ServerStreamingServerMethod <,>); reallyOutputType = inputType2.GenericTypeArguments[0]; } } var buildMethodResult = buildMethod.MakeGenericMethod(reallyInputType, reallyOutputType) .Invoke(null, new object[] { srv, method.Name, package, serviceName, methodType }); Delegate serverMethodDelegate = method.CreateDelegate(serverMethodType .MakeGenericType(reallyInputType, reallyOutputType), method.IsStatic ? null : srv); addMethod.MakeGenericMethod(reallyInputType, reallyOutputType).Invoke(builder, new[] { buildMethodResult, serverMethodDelegate }); } }