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);
        }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #7
0
        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);
        }