private ClassDescripter generateClass(Type servicerType)
        {
            var servicerName  = $"KadderServer{servicerType.Name}";
            var namespaceName = servicerType.Namespace;

            if (!string.IsNullOrWhiteSpace(_packageName))
            {
                namespaceName = _packageName;
            }

            var classDescripter = new ClassDescripter(servicerName, namespaceName)
                                  .SetBaseType(typeof(IGrpcServices).Name)
                                  .AddUsing(typeof(IGrpcServices).Namespace)
                                  .AddUsing(
                "using Grpc.Core;",
                "using System.Threading.Tasks;",
                "using Kadder;",
                "using Kadder.Utilies;",
                "using Kadder.Utils;",
                "using Microsoft.Extensions.DependencyInjection;",
                "using Kadder.Messaging;");

            classDescripter.SetAccess(AccessType.Public);
            return(classDescripter);
        }
        private MethodDescripter generateBindServicesMethod(ref ClassDescripter classDescripter, Type servicerType)
        {
            var bindServicesMethod = new MethodDescripter("BindServices", classDescripter);

            bindServicesMethod.Access = AccessType.Public;
            bindServicesMethod.SetReturnType(typeof(ServerServiceDefinition));

            bindServicesMethod.AppendCode(@"return ServerServiceDefinition.CreateBuilder()");
            foreach (var method in classDescripter.Methods)
            {
                if (method.Attributes.Count == 0)
                {
                    continue;
                }

                var fakeMethodTypeAttribute = method.Attributes.FirstOrDefault(p => p.Name == FakeCallTypeAttributeName);
                if (fakeMethodTypeAttribute == null)
                {
                    continue;
                }

                var callType = (CallType)int.Parse(fakeMethodTypeAttribute.Parameters[0]);
                bindServicesMethod.AppendCode(generateBindServicesCode(classDescripter, method, callType, servicerType));

                method.Attributes.Remove(fakeMethodTypeAttribute);
            }
            bindServicesMethod.AppendCode(@"                .Build();");

            return(bindServicesMethod);
        }
Example #3
0
        private MethodDescripter generateMethodHead(ref ClassDescripter classDescripter, MethodInfo methodInfo, bool isAsync = true)
        {
            var method = new MethodDescripter(methodInfo.Name, classDescripter, isAsync);

            method.Access = AccessType.Public;
            return(method);
        }
Example #4
0
        public IDictionary <Type, string> GenerateHandler(
            GrpcOptions options,
            GrpcClient client,
            ref CodeBuilder codeBuilder)
        {
            var types = RefelectionHelper.GetImplInterfaceTypes(
                typeof(IMessagingServicer), true, options.GetScanAssemblies());
            var grpcServiceDic = new Dictionary <Type, string>();

            foreach (var typeService in types)
            {
                var className       = typeService.Name.Remove(0, 1);
                var classDescripter = new ClassDescripter(
                    className,
                    codeBuilder.Namespace)
                                      .SetBaseType(typeService.Name)
                                      .AddUsing("System.Threading.Tasks", typeService.Namespace)
                                      .AddUsing("Kadder")
                                      .SetAccess(AccessType.Public);
                grpcServiceDic.Add(typeService, $"{codeBuilder.Namespace}.{className}");

                var baseInterfaces = typeService.GetInterfaces();
                foreach (var method in typeService.GetMethods())
                {
                    var notGrpcMethodCount = method.CustomAttributes
                                             .Count(p =>
                                                    p.AttributeType == typeof(NotGrpcMethodAttribute));
                    if (notGrpcMethodCount > 0)
                    {
                        continue;
                    }

                    var parameters = method.GetParameters();
                    if (parameters.Length != 1)
                    {
                        continue;
                    }

                    var requestName  = parameters[0].ParameterType.Name.ToLower();
                    var responseType = GetMethodReturn(method.ReturnType);
                    var methodName   = method.Name.Replace("Async", "");
                    classDescripter.CreateMember(
                        new MethodDescripter(method.Name, true)
                        .SetAccess(AccessType.Public)
                        .SetReturn($"Task<{responseType.Name}>")
                        .SetParams(
                            new ParameterDescripter(
                                parameters[0].ParameterType.Name, requestName))
                        .AppendCode($@"var client=GrpcClientExtension.ClientDic[""{client.ID.ToString()}""];")
                        .AppendCode($@"return await client.CallAsync<{parameters[0].ParameterType.Name},{responseType.Name}>({requestName}, ""{methodName}"");"))
                    .AddUsing(responseType.Namespace)
                    .AddUsing(parameters[0].ParameterType.Namespace);
                }
                codeBuilder.CreateClass(classDescripter)
                .AddAssemblyRefence(typeService.Assembly.Location);
            }
            codeBuilder.AddAssemblyRefence(this.GetType().Assembly.Location);
            return(grpcServiceDic);
        }
Example #5
0
        private MethodDescripter generateBindServicesMethod(ref ClassDescripter classDescripter)
        {
            var bindServicesMethod = new MethodDescripter("BindServices", classDescripter);

            bindServicesMethod.Access = AccessType.Public;
            bindServicesMethod.SetReturnType(typeof(ServerServiceDefinition));
            bindServicesMethod.AppendCode(@"throw new NotImplementedException();");
            return(bindServicesMethod);
        }
Example #6
0
        private string CreateAndGetDirFromNamespace(ClassDescripter _class, string prefix)
        {
            var dirPath = Path.Combine(prefix, _class.Namespace.Replace(".", "/"));

            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }
            return(dirPath);
        }
Example #7
0
        private void generateField(ref ClassDescripter classDescripter)
        {
            var invokerField = new FieldDescripter(ClassServicerInvokerName)
                               .SetType(typeof(ServicerInvoker));

            invokerField.SetAccess(AccessType.PrivateReadonly);

            classDescripter.CreateFiled(invokerField)
            .AddUsing(typeof(ServicerInvoker).Namespace);
        }
Example #8
0
        public void CodeSavePath_Test()
        {
            var codeBuilder = new CodeBuilder("test", "GenAssembly.Test");
            var codeClass   = new ClassDescripter("Person", namespaces: "GenAssembly.Test").AddUsing("System");

            codeClass.CreateMember(
                new MethodDescripter("Hello", codeClass)
                .SetAccess(AccessType.Public)
                .SetReturnType("void")
                .AppendCode("Console.WriteLine(\"Hello\");"));
            codeBuilder.CreateClass(codeClass);
            codeBuilder.BuildAsync().Wait();

            Assert.True(File.Exists(Path.Combine(CodeBuilder.CodeCachePath, "GenAssembly/Test/Person.cs")));
        }
Example #9
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);
            }
        }
        private MethodDescripter generateRpcMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo, Type parameterType, Type returnType)
        {
            var resultCode   = Helper.GenerateAwaitResultCode(returnType);
            var requestCode  = Helper.GenerateRequestCode(parameterType);
            var servicerName = methodInfo.DeclaringType.FullName;
            var methodName   = methodInfo.Name;
            var returnCode   = Helper.GenerateReturnCode(returnType);

            var method = generateMethodHead(ref classDescripter, methodInfo);

            method.Parameters.Add(new ParameterDescripter(parameterType.Name, "request"));
            method.Parameters.Add(new ParameterDescripter("ServerCallContext", "context"));
            method.AppendCode(genCallCode(servicerName, methodName, resultCode, requestCode, returnCode));
            method.SetReturnType($"Task<{returnType.Name}>");

            return(method);
        }
Example #11
0
        private void generateConstructor(ref ClassDescripter classDescripter)
        {
            var constructor = new ConstructorDescripter(classDescripter.Name);

            constructor.SetAccess(AccessType.Public);

            var providerParameter = new ParameterDescripter(typeof(ServicerInvoker).Name, "invoker");

            constructor.SetParams(providerParameter);

            var code = $@"
            {ClassServicerInvokerName} = invoker;";

            constructor.SetCode(code);

            classDescripter.CreateConstructor(constructor);
        }
Example #12
0
        private MethodDescripter generateDuplexStreamRpcMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo, Type parameterType, Type returnType)
        {
            var servicerName = getServicerName(methodInfo.DeclaringType);
            var methodName   = methodInfo.Name.Replace("Async", "");
            var requestType  = parameterType.GenericTypeArguments[0];
            var responseType = returnType.GenericTypeArguments[0];

            var method = generateMethodHead(ref classDescripter, methodInfo, false);

            method.Parameters.Add(new ParameterDescripter($"IAsyncRequestStream<{requestType.Name}>", "request"));
            method.Parameters.Add(new ParameterDescripter($"IAsyncResponseStream<{responseType.Name}>", "response"));

            method.AppendCode($@"return {ClassServicerInvokerName}.DuplexStreamAsync<{requestType.Name}, {responseType.Name}>(request, response, ""{servicerName}"", ""{methodName}"");");
            method.SetReturnType("Task");

            return(method);
        }
Example #13
0
        private MethodDescripter generateClientStreamRpcMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo, Type parameterType, Type returnType)
        {
            var servicerName = getServicerName(methodInfo.DeclaringType);
            var resultCode   = Helper.GenerateAwaitResultCode(returnType);
            var resultType   = generateRpcResponseType(returnType);
            var methodName   = methodInfo.Name.Replace("Async", "");
            var requestType  = parameterType.GenericTypeArguments[0];

            var method = generateMethodHead(ref classDescripter, methodInfo, false);

            method.Parameters.Add(new ParameterDescripter($"IAsyncRequestStream<{requestType.Name}>", "request"));

            method.AppendCode($@"{resultCode}{ClassServicerInvokerName}.ClientStreamAsync<{requestType.Name}, {returnType.Name}>(request, ""{servicerName}"", ""{methodName}"");
            {Helper.GenerateReturnCode(returnType, true)}");
            method.SetReturnType(resultType);

            return(method);
        }
        private string generateBindServicesCode(ClassDescripter @class, MethodDescripter method, CallType callType, Type servicerType)
        {
            var callInfo = getCallInfo(callType, method);

            callInfo.RequestType  = callInfo.RequestType.Replace("IAsyncStreamReader<", "").Replace("Task<", "").Replace(">", "");
            callInfo.ResponseType = callInfo.ResponseType.Replace("IServerStreamWriter<", "").Replace("Task<", "").Replace(">", "");

            var code = new StringBuilder();

            code.Append($@"                .AddMethod(new Method<{callInfo.RequestType}, {callInfo.ResponseType}>(
                    {callInfo.MethodType},
                    ""{@class.Namespace}.{servicerType.Name}"",
                    ""{method.Name}"",
                    new Marshaller<{callInfo.RequestType}>(
                        {ClassBinarySerializerName}.Serialize,
                        {ClassBinarySerializerName}.Deserialize<{callInfo.RequestType}>
                    ),
                    new Marshaller<{callInfo.ResponseType}>(
                        {ClassBinarySerializerName}.Serialize,
                        {ClassBinarySerializerName}.Deserialize<{callInfo.ResponseType}>
                    )),
                    {method.Name})");

            // This is will be remove, It's use compatible async
            if (method.Name.EndsWith("Async"))
            {
                code.AppendLine();
                code.Append($@"                .AddMethod(new Method<{callInfo.RequestType}, {callInfo.ResponseType}>(
                    {callInfo.MethodType},
                    ""{@class.Namespace}.{servicerType.Name}"",
					""{method.Name.Replace("Async","")}"",
                    new Marshaller<{callInfo.RequestType}>(
                        {ClassBinarySerializerName}.Serialize,
                        {ClassBinarySerializerName}.Deserialize<{callInfo.RequestType}>
                    ),
                    new Marshaller<{callInfo.ResponseType}>(
                        {ClassBinarySerializerName}.Serialize,
                        {ClassBinarySerializerName}.Deserialize<{callInfo.ResponseType}>
                    )),
                    {method.Name})");
            }

            return(code.ToString());
        }
Example #15
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);
        }
Example #16
0
        private ClassDescripter GenerateGrpcMethod(ClassDescripter @class, MethodInfo method, RpcParameterInfo parameter, Type[] baseInterfaces)
        {
            var className         = method.DeclaringType.Name;
            var messageName       = parameter.ParameterType.Name;
            var messageResultType = GrpcServiceBuilder.GetMethodReturn(method);
            var messageResultName = messageResultType.Name;
            var requestCode       = "messageEnvelope.Message";
            var responseCode      = "var result = ";
            var setResponseCode   = "result";

            if (parameter.IsEmpty)
            {
                requestCode = string.Empty;
            }
            if (messageResultType.IsEmpty)
            {
                responseCode    = string.Empty;
                setResponseCode = "new EmptyMessageResult()";
            }
            var code = $@"
            var envelope = new MessageEnvelope<{messageName}>();
            envelope.Message = request;  
            var grpcContext = new GrpcContext(envelope, context);
            Func<IMessageEnvelope, IServiceScope, Task<IMessageResultEnvelope>> handler = async (imsgEnvelope, scope) => 
            {{
                var messageEnvelope = (MessageEnvelope<{messageName}>) imsgEnvelope;
                {responseCode}await scope.ServiceProvider.GetService<{className}>().{method.Name}({requestCode});
                return new MessageResultEnvelope<{messageResultName}>() {{ MessageResult = {setResponseCode} }};
            }};
            var resultEnvelope = await _messageServicer.ProcessAsync(grpcContext, handler);
            return ((MessageResultEnvelope<{messageResultName}>)resultEnvelope).MessageResult;";

            return(@class.CreateMember(
                       new MethodDescripter(method.Name.Replace("Async", "") ?? "", true)
                       .SetAccess(AccessType.Public)
                       .AppendCode(code).SetReturn($"Task<{GrpcServiceBuilder.GetMethodReturn(method).Name}>")
                       .SetParams(
                           new ParameterDescripter(parameter.ParameterType.Name, "request"),
                           new ParameterDescripter("ServerCallContext", "context")))
                   .AddUsing($"using {parameter.ParameterType.Namespace};")
                   .AddUsing($"using {method.DeclaringType.Namespace};")
                   .AddUsing($"using {GrpcServiceBuilder.GetMethodReturn(method).Namespace};"));
        }
        private void generateConstructor(ref ClassDescripter classDescripter)
        {
            var constructor = new ConstructorDescripter(classDescripter.Name);

            constructor.SetAccess(AccessType.Public);

            var providerParameter = new ParameterDescripter(typeof(IObjectProvider).Name, "provider");

            constructor.SetParams(providerParameter);

            var code = $@"
            {ClassProviderName} = provider;
            {ClassBinarySerializerName} = provider.GetObject<IBinarySerializer>();
            {ClassLoggerName} = provider.GetObject<ILogger<{classDescripter.Name}>>();";

            constructor.SetCode(code);

            classDescripter.CreateConstructor(constructor);
        }
        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);
        }
Example #19
0
        private ClassDescripter generateClass(Type servicerType)
        {
            var servicerName  = $"KadderClient{servicerType.Name}";
            var namespaceName = getNamespaceName(servicerType);

            var classDescripter = new ClassDescripter(servicerName, namespaceName)
                                  .SetBaseType(servicerType.Name)
                                  .AddUsing(servicerType.Namespace)
                                  .AddUsing(
                "using Grpc.Core;",
                "using System.Threading.Tasks;",
                "using Kadder;",
                "using Kadder.Utilies;",
                "using Kadder.Utils;",
                "using Microsoft.Extensions.DependencyInjection;",
                "using Kadder.Messaging;");

            classDescripter.SetAccess(AccessType.Public);
            return(classDescripter);
        }
        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 void generateField(ref ClassDescripter classDescripter)
        {
            var binarySerializerField = new FieldDescripter(ClassBinarySerializerName)
                                        .SetType(typeof(IBinarySerializer));

            binarySerializerField.SetAccess(AccessType.PrivateReadonly);

            var providerField = new FieldDescripter(ClassProviderName)
                                .SetType(typeof(IObjectProvider));

            providerField.SetAccess(AccessType.PrivateReadonly);

            var loggerField = new FieldDescripter(ClassLoggerName).SetType(typeof(ILogger));

            loggerField.SetAccess(AccessType.PrivateReadonly);

            classDescripter.CreateFiled(binarySerializerField, providerField, loggerField)
            .AddUsing(typeof(IBinarySerializer).Namespace)
            .AddUsing(typeof(IObjectProvider).Namespace)
            .AddUsing(typeof(ILogger).Namespace);
        }
Example #22
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);
        }
Example #23
0
        private MethodDescripter generateServerStreamRpcMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo, Type parameterType, Type returnType)
        {
            var servicerName = getServicerName(methodInfo.DeclaringType);
            var requestCode  = Helper.GenerateRequestCode(parameterType);
            var methodName   = methodInfo.Name.Replace("Async", "");
            var responseType = returnType.GenericTypeArguments[0];

            if (!string.IsNullOrWhiteSpace(requestCode))
            {
                requestCode += ", ";
            }

            var method = generateMethodHead(ref classDescripter, methodInfo, false);

            method.Parameters.Add(new ParameterDescripter(parameterType.Name, "request"));
            method.Parameters.Add(new ParameterDescripter($"IAsyncResponseStream<{responseType.Name}>", "response"));

            method.AppendCode($@"return {ClassServicerInvokerName}.ServerStreamAsync<{parameterType.Name}, {responseType.Name}>({requestCode}response, ""{servicerName}"", ""{methodName}"");");
            method.SetReturnType("Task");

            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 void Test_New_Simple_Class()
        {
            var classes = new ClassDescripter("User")
                          .SetBaseType(typeof(IUser))
                          .SetAccess(AccessType.Public)
                          .CreateConstructor(
                new ConstructorDescripter("User")
                .SetAccess(AccessType.Public)
                )
                          .CreateMember(
                new MethodDescripter("Hello")
                .SetAccess(AccessType.Public)
                .SetCode("return Task.FromResult(\"hello\");")
                .SetReturn("Task<string>")
                )
                          .AddUsing("System.Threading.Tasks");
            var assembly = CodeBuilder.Instance.CreateClass(classes)
                           .Build();

            var user = (IUser)assembly.Assembly.CreateInstance("Atlantis.Common.CodeGeneration.User");

            _output.WriteLine(user.Hello().Result);
        }
Example #26
0
        private MethodDescripter generateRpcMethod(ref ClassDescripter classDescripter, MethodInfo methodInfo, Type parameterType, Type returnType)
        {
            var resultCode   = Helper.GenerateAwaitResultCode(returnType);
            var resultType   = generateRpcResponseType(returnType);
            var servicerName = getServicerName(methodInfo.DeclaringType);
            var methodName   = methodInfo.Name.Replace("Async", "");

            var method = generateMethodHead(ref classDescripter, methodInfo);

            if (parameterType != typeof(EmptyMessage))
            {
                method.Parameters.Add(new ParameterDescripter(parameterType.Name, "request"));
            }
            else
            {
                method.AppendCode("var request = new EmptyMessage();");
            }

            method.AppendCode($@"{resultCode} await {ClassServicerInvokerName}.RpcAsync<{parameterType.Name}, {returnType.Name}>(request, ""{servicerName}"", ""{methodName}"");
            {Helper.GenerateReturnCode(returnType, true)}");
            method.SetReturnType(resultType);

            return(method);
        }
Example #27
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);
        }
Example #28
0
        private static MethodDescripter GenerateNoGrpcMethod(MethodInfo method, ClassDescripter classDescripter, CodeBuilder codeBuilder)
        {
            var methodDescripter = new MethodDescripter(method.Name)
                                   .SetAccess(AccessType.Public)
                                   .SetReturn(GetReturnName(method.ReturnType))
                                   .AppendCode("throw new System.NotImplementedException();");
            var parameterDescripters = new List <ParameterDescripter>();

            foreach (var param in method.GetParameters())
            {
                parameterDescripters.Add(new ParameterDescripter(GetReturnName(param.ParameterType), param.Name));
                codeBuilder.AddAssemblyRefence(param.ParameterType.Assembly);
            }
            methodDescripter.SetParams(parameterDescripters.ToArray());

            return(methodDescripter);

            string GetReturnName(Type type)
            {
                codeBuilder.AddAssemblyRefence(type.Assembly);

                if (type.IsGenericType)
                {
                    var typeName = $"{type.FullName.Split('`')[0]}<";
                    foreach (var itemType in type.GenericTypeArguments)
                    {
                        typeName += $"{GetReturnName(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);
                }
            }
        }
        public IDictionary <Type, string> GenerateHandler(
            GrpcOptions options, GrpcClient client, ref CodeBuilder codeBuilder)
        {
            var types          = options.GetKServicers();
            var grpcServiceDic = new Dictionary <Type, string>();

            foreach (var typeService in types)
            {
                var className       = $"{typeService.Name}GrpcService";
                var classDescripter = new ClassDescripter(className, codeBuilder.Namespace)
                                      .SetBaseType(typeService.Name)
                                      .AddUsing("System.Threading.Tasks", typeService.Namespace)
                                      .AddUsing("Kadder")
                                      .SetAccess(AccessType.Public);
                grpcServiceDic.Add(typeService, $"{codeBuilder.Namespace}.{className}");

                var baseInterfaces = typeService.GetInterfaces();
                foreach (var method in typeService.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly))
                {
                    var notGrpcMethodCount = method.CustomAttributes.Count(
                        p => p.AttributeType == typeof(NotGrpcMethodAttribute));
                    if (notGrpcMethodCount > 0)
                    {
                        continue;
                    }

                    var parameters = RpcParameterInfo.Convert(method.GetParameters());
                    if (parameters.Count == 0)
                    {
                        var emptyMessageType = typeof(EmptyMessage);
                        parameters.Add(new RpcParameterInfo()
                        {
                            Name          = emptyMessageType.Name,
                            ParameterType = emptyMessageType,
                            IsEmpty       = true
                        });
                    }

                    var requestName    = parameters[0].ParameterType.Name.ToLower();
                    var responseType   = GetMethodReturn(method);
                    var returnTypeCode = $"new Task<{responseType.Name}>";
                    var returnCode     = "return ";
                    var requestCode    = requestName;
                    if (parameters[0].IsEmpty)
                    {
                        requestCode = "new EmptyMessage()";
                    }
                    if (responseType.IsEmpty)
                    {
                        returnTypeCode = $"new {method.ReturnType.Name}";
                        returnCode     = string.Empty;
                    }
                    var methodName       = method.Name.Replace("Async", "");
                    var methodDescripter = new MethodDescripter(method.Name, true)
                                           .SetAccess(AccessType.Public)
                                           .SetReturn(returnTypeCode)
                                           .AppendCode($@"var client = GrpcClientExtension.ClientDic[""{client.ID.ToString()}""];")
                                           .AppendCode($@"{returnCode}await client.CallAsync<{parameters[0].ParameterType.Name},{responseType.Name}>({requestCode}, ""{methodName}"", ""{typeService.Name}"");");
                    if (!parameters[0].IsEmpty)
                    {
                        methodDescripter.SetParams(new ParameterDescripter(parameters[0].ParameterType.Name, requestName));
                    }
                    classDescripter.CreateMember(methodDescripter)
                    .AddUsing(responseType.Namespace).AddUsing(parameters[0].ParameterType.Namespace);
                }
                codeBuilder.CreateClass(classDescripter)
                .AddAssemblyRefence(typeService.Assembly.Location);
            }
            codeBuilder.AddAssemblyRefence(this.GetType().Assembly.Location);
            return(grpcServiceDic);
        }
Example #30
0
        public ClassDescripter GenerateGrpcProxy(
            GrpcServerOptions options, CodeBuilder codeBuilder = null)
        {
            if (codeBuilder == null)
            {
                codeBuilder = CodeBuilder.Default;
            }

            var types = RefelectionHelper.GetImplInterfaceTypes(
                typeof(IMessagingServicer), true, options.GetScanAssemblies());

            var codeClass = new ClassDescripter("GrpcService", "Kadder")
                            .SetAccess(AccessType.Public)
                            .SetBaseType("IGrpcServices")
                            .AddUsing("using Grpc.Core;")
                            .AddUsing("using System.Threading.Tasks;")
                            .AddUsing("using Kadder;")
                            .AddUsing("using Kadder.Utilies;")
                            .AddUsing("using Microsoft.Extensions.DependencyInjection;")
                            .CreateFiled(
                new FieldDescripter("_binarySerializer")
                .SetAccess(AccessType.PrivateReadonly)
                .SetType(typeof(IBinarySerializer)),
                new FieldDescripter("_messageServicer")
                .SetAccess(AccessType.PrivateReadonly)
                .SetType(typeof(GrpcMessageServicer)))
                            .CreateConstructor(
                new ConstructorDescripter("GrpcService")
                .SetCode("_binarySerializer=GrpcServerBuilder.ServiceProvider.GetService<IBinarySerializer>();\n_messageServicer=GrpcServerBuilder.ServiceProvider.GetService<GrpcMessageServicer>();")
                .SetAccess(AccessType.Public));

            var bindServicesCode = new StringBuilder("return ServerServiceDefinition.CreateBuilder()\n");
            var protoServiceCode = new StringBuilder($"service {options.ServiceName} {{");
            var protoMessageCode = new StringBuilder();

            protoServiceCode.AppendLine();
            foreach (var item in types)
            {
                var baseInterfaces = item.GetInterfaces();
                foreach (var method in item.GetMethods())
                {
                    if (method.CustomAttributes.FirstOrDefault(p => p.AttributeType == typeof(NotGrpcMethodAttribute)) != null)
                    {
                        continue;
                    }
                    var parameters = method.GetParameters();
                    if (parameters.Length != 1)
                    {
                        continue;
                    }
                    CreateCallCode(method, parameters[0], baseInterfaces);
                    CreateGrpcCallCode(method, parameters[0]);

                    if (options.IsGeneralProtoFile)
                    {
                        CreateProtoCode(method, parameters[0]);
                    }
                }
            }
            bindServicesCode.AppendLine(".Build();");
            codeClass.CreateMember(
                new MethodDescripter("BindServices")
                .SetCode(bindServicesCode.ToString())
                .SetReturn("ServerServiceDefinition")
                .SetAccess(AccessType.Public));
            codeBuilder.AddAssemblyRefence(Assembly.GetExecutingAssembly().Location)
            .AddAssemblyRefence(typeof(ServerServiceDefinition).Assembly.Location)
            .AddAssemblyRefence(typeof(ServerServiceDefinition).Assembly.Location)
            .AddAssemblyRefence(typeof(ServiceProviderServiceExtensions).Assembly.Location);

            if (options.IsGeneralProtoFile)
            {
                protoServiceCode.Append("\n}\n");
                var protoStr = new StringBuilder();
                protoStr.AppendLine(@"syntax = ""proto3"";");
                protoStr.AppendLine($@"option csharp_namespace = ""{options.NamespaceName}"";");
                protoStr.AppendLine($"package {options.PackageName};\n");
                protoStr.Append(protoServiceCode);
                protoStr.AppendLine();
                protoStr.Append(protoMessageCode);
                var fileName = $"{Environment.CurrentDirectory}/{options.NamespaceName}.proto";
                if (File.Exists(fileName))
                {
                    File.Delete(fileName);
                }
                File.WriteAllText(fileName, protoStr.ToString());
                _messages = null;
            }

            codeBuilder.CreateClass(codeClass);

            return(codeClass);

            void CreateCallCode(MethodInfo method, ParameterInfo parameter, Type[] baseInterfaces)
            {
                var requestName = GetRequestName(method);

                codeClass
                .CreateMember(
                    new MethodDescripter($"{method.Name.Replace("Async", "")}", true)
                    .AppendCode(
                        $@"request.SetTypeFullName(""{requestName}"");
                            return await _messageServicer.ProcessAsync<{parameter.ParameterType.Name},{GetMethodReturn(method.ReturnType).Name}>(request,context);")
                    .SetReturn($"Task<{GetMethodReturn(method.ReturnType).Name}>")
                    .SetParams(
                        new ParameterDescripter(parameter.ParameterType.Name, "request"),
                        new ParameterDescripter("ServerCallContext", "context"))
                    .SetAccess(AccessType.Public))
                .AddUsing($"using {parameter.ParameterType.Namespace};")
                .AddUsing($"using {GetMethodReturn(method.ReturnType).Namespace};");
            }

            void CreateGrpcCallCode(MethodInfo method, ParameterInfo parameter)
            {
                bindServicesCode.AppendLine($@".AddMethod(new Method<{parameter.ParameterType.Name},{GetMethodReturn(method.ReturnType).Name}>(
                                            MethodType.Unary,
                                            ""{options.NamespaceName}.{options.ServiceName}"",
                                            ""{method.Name.Replace("Async", "")}"",
                                            new Marshaller<{parameter.ParameterType.Name}>(
                                                _binarySerializer.Serialize,
                                                _binarySerializer.Deserialize<{parameter.ParameterType.Name}>
                                            ),
                                            new Marshaller<{GetMethodReturn(method.ReturnType).Name}>(
                                                _binarySerializer.Serialize,
                                                _binarySerializer.Deserialize<{GetMethodReturn(method.ReturnType).Name}>)
                                            ),
                                        {method.Name.Replace("Async", "")})");
                codeBuilder.AddAssemblyRefence(parameter.ParameterType.Assembly.Location)
                .AddAssemblyRefence(GetMethodReturn(method.ReturnType).Assembly.Location);
            }

            void CreateProtoCode(MethodInfo method, ParameterInfo parameter)
            {
                protoServiceCode.AppendLine();
                protoServiceCode.AppendLine($"\trpc {method.Name.Replace("Async", "")}({parameter.ParameterType.Name}) returns({GetMethodReturn(method.ReturnType).Name});");
                if (!_messages.Contains(parameter.ParameterType.Name))
                {
                    protoMessageCode.AppendLine(CreateProtoMessageCode(parameter.ParameterType));
                    _messages.Add(parameter.ParameterType.Name);
                }
                if (!_messages.Contains(GetMethodReturn(method.ReturnType).Name))
                {
                    protoMessageCode.AppendLine(CreateProtoMessageCode(GetMethodReturn(method.ReturnType)));
                    _messages.Add(GetMethodReturn(method.ReturnType).Name);
                }
            }

            string CreateProtoMessageCode(Type messageType)
            {
                //    Serializer.GetProto(messageType);

                if (_messages.Contains(messageType.Name))
                {
                    return("");
                }

                var messageCode = new StringBuilder($"message {messageType.Name} {{");
                var enumCode    = new StringBuilder();
                var refenceCode = new StringBuilder();

                messageCode.AppendLine();
                var properties      = messageType.GetProperties().Where(p => p.DeclaringType == messageType);
                var isNeedAutoIndex = !(properties.FirstOrDefault(p => p.GetCustomAttribute(typeof(ProtoMemberAttribute)) != null) != null);
                int index           = 1;

                foreach (var item in properties.OrderBy(p => p.Name, new ProtoPropertyCompare()))
                {
                    if (item.GetCustomAttribute(typeof(ProtoIgnoreAttribute)) != null)
                    {
                        continue;
                    }
                    if (!isNeedAutoIndex)
                    {
                        var memberAttribute = item.GetCustomAttribute <ProtoMemberAttribute>();
                        if (memberAttribute == null)
                        {
                            continue;
                        }
                        messageCode.Append($"\t{GetFiledType(item.PropertyType)} {item.Name} = {memberAttribute.Tag};\n");
                    }
                    else
                    {
                        if (item.GetCustomAttribute(typeof(ProtoIgnoreAttribute)) != null)
                        {
                            continue;
                        }
                        messageCode.Append($"\t{GetFiledType(item.PropertyType)} {item.Name} = {index};\n");
                        index++;
                    }

                    if (!item.PropertyType.IsGenericType && string.Equals(item.PropertyType.BaseType.Name.ToLower(), "enum") && !_messages.Contains(item.PropertyType.Name))
                    {
                        GeneralEnumCode(item.PropertyType);
                        _messages.Add(item.PropertyType.Name);
                    }

                    if (item.PropertyType.IsClass && item.PropertyType.GetCustomAttribute <ProtoContractAttribute>() != null)
                    {
                        refenceCode.AppendLine(CreateProtoMessageCode(item.PropertyType));
                    }
                    if (item.PropertyType.IsArray && item.PropertyType.GetElementType().GetCustomAttribute <ProtoContractAttribute>() != null)
                    {
                        refenceCode.AppendLine(CreateProtoMessageCode(item.PropertyType.GetElementType()));
                    }
                }
                _messages.Add(messageType.Name);
                return(messageCode.Append("}\n\n").Append(enumCode).Append(refenceCode).ToString());

                string GetFiledType(Type type)
                {
                    switch (type.Name.ToLower())
                    {
                    case "int": return("int32");

                    case "int32": return("int32");

                    case "int64": return("int64");

                    case "long": return("int64");

                    case "string": return("string");

                    case "datetime": return("bcl.DateTime");

                    case "bool": return("bool");

                    case "boolean": return("bool");

                    case "double": return("double");

                    case "float": return("float");

                    default:
                        if (type.Name.Contains("[]"))
                        {
                            return($"repeated {GetFiledType(type.GetElementType())}");
                        }
                        return(type.Name);
                    }
                }

                void GeneralEnumCode(Type type)
                {
                    var zeroCode      = "\tZERO = 0;";
                    var enumFiledCode = new StringBuilder();
                    var hasDefault    = false;

                    foreach (var item in type.GetFields())
                    {
                        if (item.Name.Equals("value__"))
                        {
                            continue;
                        }
                        var values = (int)item.GetValue(null);
                        if (values <= 0)
                        {
                            hasDefault = true;
                        }
                        enumFiledCode.AppendLine($"\t{item.Name} = {values};");
                    }
                    if (hasDefault)
                    {
                        enumCode.Append($"enum {type.Name}{{\n{enumFiledCode}}}\n");
                    }
                    else
                    {
                        enumCode.Append($"enum {type.Name}{{\n{zeroCode}\n{enumFiledCode}}}\n");
                    }
                }
            }
        }