Exemplo n.º 1
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);
        }
Exemplo n.º 2
0
        internal static Configuration RegisteQueryServicer(this Configuration configuration)
        {
            var types = RefelectionHelper.GetImplInterfaceTypes(typeof(IQueryServicer), true, configuration.Setting.BussinessAssemblies);

            var codeClass = CodeBuilder.Instance.CreateClass("QueryServicerDelegateFactory",
                                                             new string[] { "IQueryServicerDelegateFactory" },
                                                             "Followme.AspNet.Core.FastCommon.Querying")
                            .AddRefence("using Followme.AspNet.Core.FastCommon.Components;",
                                        "using System.Threading.Tasks;",
                                        "using Followme.AspNet.Core.FastCommon.Querying;");

            var needResult = 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;
                    }
                    if (!method.ReturnType.Name.Contains("Task"))
                    {
                        throw new InvalidOperationException($"Please use async at method({type.FullName} -> {method.Name})");
                    }

                    needResult.AppendLine($@"if(string.Equals(message.GetTypeFullName(),""{parameters[0].ParameterType.FullName}""))
                                {{
                                    return async (m)=>{{return (await ObjectContainer.Resolve<{type.Name}>().{method.Name}(message as {parameters[0].ParameterType.FullName})) as TMessageResult;}} ;
                                }}");

                    CodeBuilder.Instance.AddAssemblyRefence(parameters[0].ParameterType.Assembly.Location);
                }
                codeClass.AddRefence($"using {type.Namespace};");
                CodeBuilder.Instance.AddAssemblyRefence(type.Assembly.Location);
            }

            needResult.Append("return null;");

            codeClass.CreateMember("GetHandleDelegateAsync<TMessage,TMessageResult>",
                                   needResult.ToString(),
                                   "Func<TMessage,Task<TMessageResult>>",
                                   new CodeParameter[] { new CodeParameter("TMessage", "message") },
                                   new CodeMemberAttribute("public"),
                                   "TMessageResult:class where TMessage:BaseMessage");

            var codeAssembly = CodeBuilder.Instance.AddAssemblyRefence(configuration.Setting.BussinessAssemblies.Select(p => p.Location).ToArray())
                               .AddAssemblyRefence(Assembly.GetExecutingAssembly().Location);

            return(configuration);
        }
Exemplo n.º 3
0
        public static Configuration RegisterRabbitMQ(this Configuration configuration, string rabbitMQSettingConfigName)
        {
            ObjectContainer.Register <IRabbitMessagePublisher, RabbitMessagePublisher>();
            configuration.Setting.SetRabbitMQSetting(configuration.GetSetting <RabbitMQSetting>(rabbitMQSettingConfigName) ?? throw new ArgumentNullException("Please setting rabbit!"));
            var types = RefelectionHelper.GetImplInterfaceTypes(typeof(IRabbitMessagingHandler), false, configuration.Setting.BussinessAssemblies);

            foreach (var type in types)
            {
                if (type.IsAbstract)
                {
                    continue;
                }
                ObjectContainer.Register(type, LifeScope.Transient);
                _metadatas.Add(type);
            }
            return(configuration);
        }
        private static void RegisterBussinessCode(Configuration configuration, string namespaceName, string packageName, string serviceName, bool isGeneralProtoFile)
        {
            var types = RefelectionHelper.GetImplInterfaceTypes(typeof(IMessagingServicer), true, configuration.Setting.BussinessAssemblies);
            var queryServicerDeclareList = new List <string>();

            var codeClass = CodeBuilder.Instance.CreateClass("GrpcService", new string[] { "IGrpcServices" }, "Followme.AspNet.Core.FastCommon.ThirdParty.GrpcServer")
                            .AddRefence("using Grpc.Core;")
                            .AddRefence("using System.Threading.Tasks;")
                            .AddRefence("using Followme.AspNet.Core.FastCommon.Serializing;")
                            .AddRefence("using Followme.AspNet.Core.FastCommon.Infrastructure;")
                            .CreateFiled("_binarySerializer", "IBinarySerializer", new CodeMemberAttribute("private", "readonly"))
                            .CreateFiled("_messageServicer", "GrpcMessageServicer", new CodeMemberAttribute("private", "readonly"))
                            .CreateConstructor("_binarySerializer=ObjectContainer.Resolve<IBinarySerializer>();\n_messageServicer=new GrpcMessageServicer();");
            var bindServicesCode = new StringBuilder("return ServerServiceDefinition.CreateBuilder()\n");
            var protoServiceCode = new StringBuilder($"service {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 (isGeneralProtoFile)
                    {
                        CreateProtoCode(method, parameters[0]);
                    }
                }
            }
            bindServicesCode.AppendLine(".Build();");
            codeClass.CreateMember("BindServices", bindServicesCode.ToString(), "ServerServiceDefinition", null, new CodeMemberAttribute("public"));
            CodeBuilder.Instance.AddAssemblyRefence(Assembly.GetExecutingAssembly().Location)
            .AddAssemblyRefence(typeof(ServerServiceDefinition).Assembly.Location)
            .AddAssemblyRefence(typeof(ServerServiceDefinition).Assembly.Location);

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

            void CreateCallCode(MethodInfo method, ParameterInfo parameter, Type[] baseInterfaces)
            {
                string codeMessageType = "MessageExecutingType.Query";

                if (baseInterfaces.Contains(typeof(ICommandServicer)))
                {
                    codeMessageType = "MessageExecutingType.Command";
                }

                codeClass.CreateMember($"{method.Name.Replace("Async","")}",
                                       $@"request.SetMessageExecutingType({codeMessageType});
                                               request.SetTypeFullName(""{parameter.ParameterType.FullName}"");
                                               return _messageServicer.ProcessAsync<{parameter.ParameterType.Name},{GetMethodReturn(method.ReturnType).Name}>(request,context);",
                                       $"Task<{GetMethodReturn(method.ReturnType).Name}>",
                                       new CodeParameter[]
                {
                    new CodeParameter(parameter.ParameterType.Name, "request"),
                    new CodeParameter("ServerCallContext", "context")
                },
                                       new CodeMemberAttribute("public"))
                .AddRefence($"using {parameter.ParameterType.Namespace};")
                .AddRefence($"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,
                                            ""{namespaceName}.{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.Instance.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");
                    }
                }
            }
        }
Exemplo n.º 5
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);
        }
Exemplo n.º 6
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");
                    }
                }
            }
        }