GrpcServiceExtension.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using Grpc.Core;
  2. using TEAMModelOS.SDK.Module.GrpcServer.Interfaces;
  3. using TEAMModelOS.SDK.Module.GrpcServer.Internal;
  4. using TEAMModelOS.SDK.Module.GrpcServer.Model;
  5. using TEAMModelOS.SDK.Module.GrpcServer.Model.Meta;
  6. using System;
  7. using System.Collections;
  8. using System.Reflection;
  9. using TEAMModelOS.SDK.Helper.Common.ReflectorExtensions;
  10. namespace TEAMModelOS.SDK.Module.GrpcServer.Extensions
  11. {
  12. public static class GrpcServiceExtension
  13. {
  14. /// <summary>
  15. /// 生成Grpc方法(CodeFirst方式,用于生成BaseService)
  16. /// </summary>
  17. /// <typeparam name="TRequest"></typeparam>
  18. /// <typeparam name="TResponse"></typeparam>
  19. /// <param name="srv"></param>
  20. /// <param name="methodName"></param>
  21. /// <param name="package"></param>
  22. /// <param name="srvName"></param>
  23. /// <param name="mType"></param>
  24. /// <returns></returns>
  25. public static Method<TRequest, TResponse> BuildMethod<TRequest, TResponse>(this IGrpcService srv,
  26. string methodName, string package = null, string srvName = null, MethodType mType = MethodType.Unary)
  27. {
  28. var serviceName = srvName ??
  29. GrpcExtensionsOptions.Instance.GlobalService ??
  30. srv.GetType().Name;
  31. var pkg = package ?? GrpcExtensionsOptions.Instance.GlobalPackage;
  32. if (!string.IsNullOrWhiteSpace(pkg))
  33. {
  34. serviceName = $"{pkg}.{serviceName}";
  35. }
  36. #region 为生成proto收集信息
  37. if (!(srv is IGrpcBaseService) || GrpcExtensionsOptions.Instance.GenBaseServiceProtoEnable)
  38. {
  39. ProtoInfo.Methods.Add(new ProtoMethodInfo
  40. {
  41. ServiceName = serviceName,
  42. MethodName = methodName,
  43. RequestName = typeof(TRequest).Name,
  44. ResponseName = typeof(TResponse).Name,
  45. MethodType = mType
  46. });
  47. ProtoGenerator.AddProto<TRequest>(typeof(TRequest).Name);
  48. ProtoGenerator.AddProto<TResponse>(typeof(TResponse).Name);
  49. }
  50. #endregion
  51. var request = Marshallers.Create<TRequest>((arg) => ProtobufExtensions.Serialize<TRequest>(arg), data => ProtobufExtensions.Deserialize<TRequest>(data));
  52. var response = Marshallers.Create<TResponse>((arg) => ProtobufExtensions.Serialize<TResponse>(arg), data => ProtobufExtensions.Deserialize<TResponse>(data));
  53. return new Method<TRequest, TResponse>(mType, serviceName, methodName, request, response);
  54. }
  55. /// <summary>
  56. /// 生成Grpc元数据信息
  57. /// </summary>
  58. /// <param name="builder"></param>
  59. public static void BuildMeta(IDictionary callHandlers)
  60. {
  61. var bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
  62. //获取Grpc元数据信息
  63. foreach (DictionaryEntry callHandler in callHandlers)
  64. {
  65. //反射获取Handlers
  66. var hFiled = callHandler.Value.GetFieldValue<Delegate>("handler", bindingFlags);
  67. var handler = hFiled.Item1;
  68. var types = hFiled.Item2.DeclaringType.GenericTypeArguments;
  69. MetaModel.Methods.Add((new MetaMethodModel
  70. {
  71. FullName = callHandler.Key.ToString(),
  72. RequestType = types[0],
  73. ResponseType = types[1],
  74. Handler = handler
  75. }));
  76. }
  77. }
  78. }
  79. }