private MethodDescripter generateServerStreamRpcMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo, Type parameterType, Type returnType) { var requestCode = $"{Helper.GenerateRequestCode(parameterType)}, responseStream"; var servicerName = methodInfo.DeclaringType.FullName; var responseType = returnType.GenericTypeArguments[0]; var methodName = methodInfo.Name; var method = generateMethodHead(ref classDescripter, methodInfo); method.Parameters.Add(new ParameterDescripter(parameterType.Name, "request")); method.Parameters.Add(new ParameterDescripter($"IServerStreamWriter<{responseType.Name}>", "response")); method.Parameters.Add(new ParameterDescripter("ServerCallContext", "context")); method.AppendCode($"var responseStream = new AsyncResponseStream<{responseType.Name}>(response);"); method.AppendCode(genCallCode(servicerName, methodName, string.Empty, requestCode, string.Empty)); method.SetReturnType("Task"); classDescripter.AddUsing(typeof(IServerStreamWriter <>).Namespace); classDescripter.AddUsing(typeof(AsyncRequestStream <>).Namespace); return(method); }
private MethodDescripter generateClientStreamRpcMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo, Type parameterType, Type returnType) { var resultCode = Helper.GenerateAwaitResultCode(returnType); var servicerName = methodInfo.DeclaringType.FullName; var methodName = methodInfo.Name; var requestParameterType = parameterType.GenericTypeArguments[0]; var returnCode = Helper.GenerateReturnCode(returnType); var method = generateMethodHead(ref classDescripter, methodInfo); method.Parameters.Add(new ParameterDescripter($"IAsyncStreamReader<{requestParameterType.Name}>", "request")); method.Parameters.Add(new ParameterDescripter("ServerCallContext", "context")); method.AppendCode($"var streamReq = new AsyncRequestStream<{requestParameterType.Name}>(request);"); method.AppendCode(genCallCode(servicerName, methodName, resultCode, "streamReq", returnCode)); method.SetReturnType($"Task<{returnType.Name}>"); classDescripter.AddUsing(typeof(IAsyncStreamReader <>).Namespace); classDescripter.AddUsing(typeof(AsyncRequestStream <>).Namespace); return(method); }
private string GetReturnName(ref ClassDescripter classDescripter, Type type) { classDescripter.AddUsing(type.Namespace); if (type.IsGenericType) { var typeName = $"{type.FullName.Split('`')[0]}<"; foreach (var itemType in type.GenericTypeArguments) { typeName += $"{GetReturnName(ref classDescripter, itemType)},"; } return($"{typeName.Remove(typeName.Length - 1)}>"); } else if (type.IsValueType || type.Name.StartsWith("String")) { switch (type.Name) { case "Int16": return("short"); case "Int32": return("int"); case "Int64": return("long"); case "UInt16": return("ushort"); case "UInt32": return("uint"); case "UInt64": return("ulong"); case "String": return("string"); case "Double": return("double"); case "Single": return("float"); case "Decimal": return("decimal"); case "Boolean": return("bool"); default: return(string.Empty); } } else { return(type.FullName); } }
private MethodDescripter generateNoGrpcMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo) { var method = new MethodDescripter(methodInfo.Name, classDescripter, false); method.Access = AccessType.Public; method.SetReturnType(GetReturnName(ref classDescripter, methodInfo.ReturnType)); var parameterDescripters = new List <ParameterDescripter>(); foreach (var param in methodInfo.GetParameters()) { classDescripter.AddUsing(param.ParameterType.Namespace); method.Parameters.Add(new ParameterDescripter(GetReturnName(ref classDescripter, param.ParameterType), param.Name)); } method.AppendCode("throw new System.NotImplementedException();"); return(method); }
private MethodDescripter generateMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo) { if (methodInfo.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(NotGrpcMethodAttribute)) != null) { return(generateNoGrpcMethod(ref classDescripter, methodInfo)); } var parameterType = methodInfo.ParseMethodParameter(); var returnType = methodInfo.ParseMethodReturnParameter(); var callType = Helper.AnalyseCallType(parameterType, returnType); classDescripter.AddUsing(parameterType.Namespace, returnType.Namespace, methodInfo.DeclaringType.Namespace); var method = new MethodDescripter("", classDescripter); switch (callType) { case CallType.Rpc: method = generateRpcMethod(ref classDescripter, methodInfo, parameterType, returnType); break; case CallType.ClientStreamRpc: method = generateClientStreamRpcMethod(ref classDescripter, methodInfo, parameterType, returnType); break; case CallType.ServerStreamRpc: method = generateServerStreamRpcMethod(ref classDescripter, methodInfo, parameterType, returnType); break; case CallType.DuplexStreamRpc: method = generateDuplexStreamRpcMethod(ref classDescripter, methodInfo, parameterType, returnType); break; default: throw new InvalidOperationException("Invalid Method definition!"); } return(method); }
private MethodDescripter generateMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo) { var parameterType = methodInfo.ParseMethodParameter(); var returnType = methodInfo.ParseMethodReturnParameter(); var callType = Helper.AnalyseCallType(parameterType, returnType); classDescripter.AddUsing(parameterType.Namespace, returnType.Namespace, methodInfo.DeclaringType.Namespace); var method = new MethodDescripter("", classDescripter); switch (callType) { case CallType.Rpc: method = generateRpcMethod(ref classDescripter, methodInfo, parameterType, returnType); break; case CallType.ClientStreamRpc: method = generateClientStreamRpcMethod(ref classDescripter, methodInfo, parameterType, returnType); break; case CallType.ServerStreamRpc: method = generateServerStreamRpcMethod(ref classDescripter, methodInfo, parameterType, returnType); break; case CallType.DuplexStreamRpc: method = generateDuplexStreamRpcMethod(ref classDescripter, methodInfo, parameterType, returnType); break; default: throw new InvalidOperationException("Invalid Method definition!"); } var methodTypeAttribute = new AttributeDescripter(FakeCallTypeAttributeName, ((int)callType).ToString()); method.Attributes.Add(methodTypeAttribute); return(method); }
public ClassDescripter GenerateHandlerProxy( Assembly[] assemblies, CodeBuilder codeBuilder = null) { if (codeBuilder == null) { codeBuilder = CodeBuilder.Default; } var types = RefelectionHelper.GetImplInterfaceTypes( typeof(IMessagingServicer), true, assemblies); var codeClass = new ClassDescripter("MessageServicerProxy", "Kadder") .SetAccess(AccessType.Public) .SetBaseType("IMessageServicerProxy") .AddUsing( "using System;", "using Kadder.Utilies;", "using System.Threading.Tasks;", "using Microsoft.Extensions.DependencyInjection;"); var needResult = new StringBuilder(); var noResult = new StringBuilder(); foreach (var type in types) { var methods = type.GetMethods(); foreach (var method in methods) { var parameters = method.GetParameters(); if (parameters.Length != 1) { continue; } var requestName = GetRequestName(method); if (method.ReturnType == typeof(void)) { noResult.AppendLine( $@"if(string.Equals(message.GetTypeFullName(),""{requestName}"")) {{ return async (m)=>await {{serviceProvider.GetService<{type.Name}>().{method.Name}(message as {parameters[0].ParameterType.FullName});}} ; }}"); } else { needResult.AppendLine( $@"if(string.Equals(message.GetTypeFullName(),""{requestName}"")) {{ return async (m)=>{{return (await serviceProvider.GetService<{type.Name}>().{method.Name}(message as {parameters[0].ParameterType.FullName})) as TMessageResult;}} ; }}"); } codeBuilder.AddAssemblyRefence(parameters[0].ParameterType.Assembly.Location); } codeClass.AddUsing($"using {type.Namespace};"); codeBuilder.AddAssemblyRefence(type.Assembly.Location); } noResult.Append("return null;"); needResult.Append("return null;"); codeClass.CreateMember( new MethodDescripter("GetHandleDelegate<TMessage,TMessageResult>") .SetAccess(AccessType.Public) .SetReturn("Func<TMessage,Task<TMessageResult>>") .SetCode(needResult.ToString()) .SetParams( new ParameterDescripter("TMessage", "message"), new ParameterDescripter("IServiceProvider", "serviceProvider")) .SetTypeParameters( new TypeParameterDescripter("TMessageResult", "class"), new TypeParameterDescripter("TMessage", "BaseMessage")), new MethodDescripter("GetHandleDelegate<TMessage>") .SetAccess(AccessType.Public) .SetReturn("Func<TMessage,Task>") .SetCode(noResult.ToString()) .SetParams( new ParameterDescripter("TMessage", "message"), new ParameterDescripter("IServiceProvider", "serviceProvider")) .SetTypeParameters( new TypeParameterDescripter("TMessage", "BaseMessage"))); codeBuilder .AddAssemblyRefence(assemblies.Select(p => p.Location).ToArray()) .AddAssemblyRefence(Assembly.GetExecutingAssembly().Location) .AddAssemblyRefence(typeof(ServiceProviderServiceExtensions).Assembly.Location) .CreateClass(codeClass); return(codeClass); }