using Grpc.Core;
using TEAMModelOS.SDK.Module.GrpcServer.Interfaces;
using TEAMModelOS.SDK.Module.GrpcServer.Internal;
using TEAMModelOS.SDK.Module.GrpcServer.Model;
using TEAMModelOS.SDK.Module.GrpcServer.Model.Meta;
using System;
using System.Collections;
using System.Reflection;
using TEAMModelOS.SDK.Helper.Common.ReflectorExtensions;
namespace TEAMModelOS.SDK.Module.GrpcServer.Extensions
{
public static class GrpcServiceExtension
{
///
/// 生成Grpc方法(CodeFirst方式,用于生成BaseService)
///
///
///
///
///
///
///
///
///
public static Method BuildMethod(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(typeof(TRequest).Name);
ProtoGenerator.AddProto(typeof(TResponse).Name);
}
#endregion
var request = Marshallers.Create((arg) => ProtobufExtensions.Serialize(arg), data => ProtobufExtensions.Deserialize(data));
var response = Marshallers.Create((arg) => ProtobufExtensions.Serialize(arg), data => ProtobufExtensions.Deserialize(data));
return new Method(mType, serviceName, methodName, request, response);
}
///
/// 生成Grpc元数据信息
///
///
public static void BuildMeta(IDictionary callHandlers)
{
var bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
//获取Grpc元数据信息
foreach (DictionaryEntry callHandler in callHandlers)
{
//反射获取Handlers
var hFiled = callHandler.Value.GetFieldValue("handler", bindingFlags);
var handler = hFiled.Item1;
var types = hFiled.Item2.DeclaringType.GenericTypeArguments;
MetaModel.Methods.Add((new MetaMethodModel
{
FullName = callHandler.Key.ToString(),
RequestType = types[0],
ResponseType = types[1],
Handler = handler
}));
}
}
}
}