//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有 // 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权 // CSDN博客:https://blog.csdn.net/qq_40374647 // 哔哩哔哩视频:https://space.bilibili.com/94253567 // Gitee源代码仓库:https://gitee.com/RRQM_Home // Github源代码仓库:https://github.com/RRQM // API首页:https://touchsocket.net/ // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using TouchSocket.Core; namespace TouchSocket.Rpc { /// /// Rpc方法属性基类 /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)] public abstract class RpcAttribute : Attribute { /// /// 构造函数 /// public RpcAttribute() { this.Exceptions.Add(typeof(TimeoutException), "调用超时"); this.Exceptions.Add(typeof(RpcInvokeException), "Rpc调用异常"); this.Exceptions.Add(typeof(Exception), "其他异常"); } /// /// 类生成器 /// public ClassCodeGenerator ClassCodeGenerator { get; private set; } /// /// 异常提示 /// public Dictionary Exceptions { get; } = new Dictionary(); /// /// 生成代码 /// public CodeGeneratorFlag GeneratorFlag { get; set; } = CodeGeneratorFlag.InstanceSync | CodeGeneratorFlag.InstanceAsync | CodeGeneratorFlag.ExtensionSync | CodeGeneratorFlag.ExtensionAsync | CodeGeneratorFlag.InterfaceSync | CodeGeneratorFlag.InterfaceAsync; /// /// 生成泛型方法的约束 /// public Type[] GenericConstraintTypes { get; set; } = new Type[] { typeof(IRpcClient) }; /// /// 调用键。 /// public string InvokeKey { get; set; } /// /// 是否仅以函数名调用,当为True是,调用时仅需要传入方法名即可。 /// public bool MethodInvoke { get; set; } /// /// 重新指定生成的函数名称。可以使用类似“JsonRpc_{0}”的模板格式。 /// public string MethodName { get; set; } /// /// 获取注释信息 /// /// /// public virtual string GetDescription(RpcMethod rpcMethod) { return string.IsNullOrEmpty(rpcMethod.GetDescription()) ? "无注释信息" : rpcMethod.GetDescription(); } /// /// 获取扩展的代理代码 /// /// /// public virtual string GetExtensionsMethodProxyCode(RpcMethod rpcMethod) { var codeString = new StringBuilder(); var description = this.GetDescription(rpcMethod); var parametersStr = this.GetParameters(rpcMethod, out var isOut, out var isRef, out var parameters); var InterfaceTypes = this.GetGenericConstraintTypes(); if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.ExtensionSync)) { codeString.AppendLine("///"); codeString.AppendLine($"///{description}"); codeString.AppendLine("///"); foreach (var item in this.Exceptions) { codeString.AppendLine($"/// {item.Value}"); } codeString.Append("public static "); codeString.Append(this.GetReturn(rpcMethod, false)); codeString.Append(' '); codeString.Append(this.GetMethodName(rpcMethod, false)); codeString.Append("(");//方法参数 codeString.Append($"this TClient client"); codeString.Append(','); for (var i = 0; i < parametersStr.Count; i++) { if (i > 0) { codeString.Append(','); } codeString.Append(parametersStr[i]); } if (parametersStr.Count > 0) { codeString.Append(','); } codeString.Append(this.GetInvokeOption()); codeString.AppendLine(") where TClient:"); for (var i = 0; i < InterfaceTypes.Length; i++) { if (i > 0) { codeString.Append(','); } codeString.Append(InterfaceTypes[i].FullName); } codeString.AppendLine("{");//方法开始 if (parametersStr.Count > 0) { codeString.Append($"object[] parameters = new object[]"); codeString.Append('{'); foreach (var parameter in parameters) { if (parameter.ParameterType.Name.Contains("&") && parameter.IsOut) { codeString.Append($"default({this.GetProxyParameterName(parameter)})"); } else { codeString.Append(parameter.Name); } if (parameter != parameters[parameters.Length - 1]) { codeString.Append(','); } } codeString.AppendLine("};"); if (isOut || isRef) { codeString.Append($"Type[] types = new Type[]"); codeString.Append('{'); foreach (var parameter in parameters) { codeString.Append($"typeof({this.GetProxyParameterName(parameter)})"); if (parameter != parameters[parameters.Length - 1]) { codeString.Append(','); } } codeString.AppendLine("};"); } } if (rpcMethod.HasReturn) { if (parametersStr.Count == 0) { codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, null);"); } else if (isOut || isRef) { codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption,ref parameters,types);"); } else { codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, parameters);"); } } else { if (parametersStr.Count == 0) { codeString.Append("client.Invoke("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, null);"); } else if (isOut || isRef) { codeString.Append("client.Invoke("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption,ref parameters,types);"); } else { codeString.Append("client.Invoke("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, parameters);"); } } if (isOut || isRef) { codeString.AppendLine("if(parameters!=null)"); codeString.AppendLine("{"); for (var i = 0; i < parameters.Length; i++) { codeString.AppendLine(string.Format("{0}=({1})parameters[{2}];", parameters[i].Name, this.GetProxyParameterName(parameters[i]), i)); } codeString.AppendLine("}"); if (isOut) { codeString.AppendLine("else"); codeString.AppendLine("{"); for (var i = 0; i < parameters.Length; i++) { if (parameters[i].IsOut) { codeString.AppendLine(string.Format("{0}=default({1});", parameters[i].Name, this.GetProxyParameterName(parameters[i]))); } } codeString.AppendLine("}"); } } if (rpcMethod.HasReturn) { codeString.AppendLine("return returnData;"); } codeString.AppendLine("}"); } //以下生成异步 if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.ExtensionAsync) /*&& !isOut && !isRef*/) { codeString.AppendLine("///"); codeString.AppendLine($"///{description}"); codeString.AppendLine("///"); if (rpcMethod.HasReturn && !isOut && !isRef) { codeString.Append("public static async "); } else { codeString.Append("public static "); } codeString.Append(this.GetReturn(rpcMethod, true)); codeString.Append(' '); codeString.Append(this.GetMethodName(rpcMethod, true)); codeString.Append("(");//方法参数 codeString.Append($"this TClient client"); codeString.Append(','); for (var i = 0; i < parametersStr.Count; i++) { if (i > 0) { codeString.Append(','); } codeString.Append(parametersStr[i]); } if (parametersStr.Count > 0) { codeString.Append(','); } codeString.Append(this.GetInvokeOption()); codeString.AppendLine(") where TClient:"); for (var i = 0; i < InterfaceTypes.Length; i++) { if (i > 0) { codeString.Append(','); } codeString.Append(InterfaceTypes[i].FullName); } codeString.AppendLine("{");//方法开始 if (parametersStr.Count > 0) { codeString.Append($"object[] parameters = new object[]"); codeString.Append('{'); foreach (var parameter in parameters) { if (parameter.ParameterType.Name.Contains("&") && parameter.IsOut) { codeString.Append($"default({this.GetProxyParameterName(parameter)})"); } else { codeString.Append(parameter.Name); } if (parameter != parameters[parameters.Length - 1]) { codeString.Append(','); } } codeString.AppendLine("};"); if (isOut || isRef) { codeString.Append($"Type[] types = new Type[]"); codeString.Append('{'); foreach (var parameter in parameters) { codeString.Append($"typeof({this.GetProxyParameterName(parameter)})"); if (parameter != parameters[parameters.Length - 1]) { codeString.Append(','); } } codeString.AppendLine("};"); } } if (rpcMethod.HasReturn) { if (parametersStr.Count == 0) { codeString.Append(string.Format("return ({0}) await client.InvokeAsync", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, null);"); } else if (isOut || isRef) { codeString.Append(string.Format("{0} returnData=({0})client.Invoke", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption,ref parameters,types);"); } else { codeString.Append(string.Format("return ({0}) await client.InvokeAsync", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, parameters);"); } } else { if (parametersStr.Count == 0) { codeString.Append("return client.InvokeAsync("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, null);"); } else if (isOut || isRef) { codeString.Append("client.Invoke("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption,ref parameters,types);"); } else { codeString.Append("return client.InvokeAsync("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, parameters);"); } } if (isOut || isRef) { codeString.AppendLine("if(parameters!=null)"); codeString.AppendLine("{"); for (var i = 0; i < parameters.Length; i++) { codeString.AppendLine(string.Format("{0}=({1})parameters[{2}];", parameters[i].Name, this.GetProxyParameterName(parameters[i]), i)); } codeString.AppendLine("}"); if (isOut) { codeString.AppendLine("else"); codeString.AppendLine("{"); for (var i = 0; i < parameters.Length; i++) { if (parameters[i].IsOut) { codeString.AppendLine(string.Format("{0}=default({1});", parameters[i].Name, this.GetProxyParameterName(parameters[i]))); } } codeString.AppendLine("}"); } } if (isOut || isRef) { if (rpcMethod.HasReturn) { codeString.AppendLine(string.Format("return Task.FromResult<{0}>(returnData);", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); } else { codeString.AppendLine(string.Format("return EasyTask.CompletedTask;")); } } codeString.AppendLine("}"); } return codeString.ToString(); } /// /// 获取生成的函数泛型限定名称。默认 /// /// public virtual Type[] GetGenericConstraintTypes() { return this.GenericConstraintTypes; } /// /// 获取生成实体类时的代码块 /// /// /// public virtual string GetInstanceProxyCode(RpcMethod rpcMethod) { var codeString = new StringBuilder(); var description = this.GetDescription(rpcMethod); var parametersStr = this.GetParameters(rpcMethod, out var isOut, out var isRef, out var parameters); if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InstanceSync)) { codeString.AppendLine("///"); codeString.AppendLine($"///{description}"); codeString.AppendLine("///"); foreach (var item in this.Exceptions) { codeString.AppendLine($"/// {item.Value}"); } codeString.Append("public "); codeString.Append(this.GetReturn(rpcMethod, false)); codeString.Append(' '); codeString.Append(this.GetMethodName(rpcMethod, false)); codeString.Append('(');//方法参数 for (var i = 0; i < parametersStr.Count; i++) { if (i > 0) { codeString.Append(','); } codeString.Append(parametersStr[i]); } if (parametersStr.Count > 0) { codeString.Append(','); } codeString.Append(this.GetInvokeOption()); codeString.AppendLine(")"); codeString.AppendLine("{");//方法开始 codeString.AppendLine("if(Client==null)"); codeString.AppendLine("{"); codeString.AppendLine("throw new RpcException(\"IRpcClient为空,请先初始化或者进行赋值\");"); codeString.AppendLine("}"); if (parametersStr.Count > 0) { codeString.Append($"object[] parameters = new object[]"); codeString.Append('{'); foreach (var parameter in parameters) { if (parameter.ParameterType.Name.Contains("&") && parameter.IsOut) { codeString.Append($"default({this.GetProxyParameterName(parameter)})"); } else { codeString.Append(parameter.Name); } if (parameter != parameters[parameters.Length - 1]) { codeString.Append(','); } } codeString.AppendLine("};"); if (isOut || isRef) { codeString.Append($"Type[] types = new Type[]"); codeString.Append('{'); foreach (var parameter in parameters) { codeString.Append($"typeof({this.GetProxyParameterName(parameter)})"); if (parameter != parameters[parameters.Length - 1]) { codeString.Append(','); } } codeString.AppendLine("};"); } } if (rpcMethod.HasReturn) { if (parametersStr.Count == 0) { codeString.Append(string.Format("{0} returnData=({0})Client.Invoke", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, null);"); } else if (isOut || isRef) { codeString.Append(string.Format("{0} returnData=({0})Client.Invoke", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append("("); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption,ref parameters,types);"); } else { codeString.Append(string.Format("{0} returnData=({0})Client.Invoke", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append("("); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, parameters);"); } } else { if (parametersStr.Count == 0) { codeString.Append("Client.Invoke("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, null);"); } else if (isOut || isRef) { codeString.Append("Client.Invoke("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption,ref parameters,types);"); } else { codeString.Append("Client.Invoke("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, parameters);"); } } if (isOut || isRef) { codeString.AppendLine("if(parameters!=null)"); codeString.AppendLine("{"); for (var i = 0; i < parameters.Length; i++) { codeString.AppendLine(string.Format("{0}=({1})parameters[{2}];", parameters[i].Name, this.GetProxyParameterName(parameters[i]), i)); } codeString.AppendLine("}"); if (isOut) { codeString.AppendLine("else"); codeString.AppendLine("{"); for (var i = 0; i < parameters.Length; i++) { if (parameters[i].IsOut) { codeString.AppendLine(string.Format("{0}=default({1});", parameters[i].Name, this.GetProxyParameterName(parameters[i]))); } } codeString.AppendLine("}"); } } if (rpcMethod.HasReturn) { codeString.AppendLine("return returnData;"); } codeString.AppendLine("}"); } //以下生成异步 if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InstanceAsync)) { codeString.AppendLine("///"); codeString.AppendLine($"///{description}"); codeString.AppendLine("///"); if (rpcMethod.HasReturn && (!isOut && !isRef)) { codeString.Append("public async "); } else { codeString.Append("public "); } codeString.Append(this.GetReturn(rpcMethod, true)); codeString.Append(' '); codeString.Append(this.GetMethodName(rpcMethod, true)); codeString.Append('(');//方法参数 for (var i = 0; i < parametersStr.Count; i++) { if (i > 0) { codeString.Append(','); } codeString.Append(parametersStr[i]); } if (parametersStr.Count > 0) { codeString.Append(','); } codeString.Append(this.GetInvokeOption()); codeString.AppendLine(")"); codeString.AppendLine("{");//方法开始 codeString.AppendLine("if(Client==null)"); codeString.AppendLine("{"); codeString.AppendLine("throw new RpcException(\"IRpcClient为空,请先初始化或者进行赋值\");"); codeString.AppendLine("}"); if (parametersStr.Count > 0) { codeString.Append($"object[] parameters = new object[]"); codeString.Append('{'); foreach (var parameter in parameters) { if (parameter.ParameterType.Name.Contains("&") && parameter.IsOut) { codeString.Append($"default({this.GetProxyParameterName(parameter)})"); } else { codeString.Append(parameter.Name); } if (parameter != parameters[parameters.Length - 1]) { codeString.Append(','); } } codeString.AppendLine("};"); if (isOut || isRef) { codeString.Append($"Type[] types = new Type[]"); codeString.Append('{'); foreach (var parameter in parameters) { codeString.Append($"typeof({this.GetProxyParameterName(parameter)})"); if (parameter != parameters[parameters.Length - 1]) { codeString.Append(','); } } codeString.AppendLine("};"); } } if (rpcMethod.HasReturn) { if (parametersStr.Count == 0) { codeString.Append(string.Format("return ({0}) await Client.InvokeAsync", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, null);"); } else if (isOut || isRef) { codeString.Append(string.Format("{0} returnData=({0})Client.Invoke", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption,ref parameters,types);"); } else { codeString.Append(string.Format("return ({0}) await Client.InvokeAsync", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append('('); codeString.Append(string.Format("typeof({0}),", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, parameters);"); } } else { if (parametersStr.Count == 0) { codeString.Append("return Client.InvokeAsync("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, null);"); } else if (isOut || isRef) { codeString.Append("Client.Invoke("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption,ref parameters,types);"); } else { codeString.Append("return Client.InvokeAsync("); codeString.Append($"\"{this.GetInvokenKey(rpcMethod)}\""); codeString.AppendLine(",invokeOption, parameters);"); } } if (isOut || isRef) { codeString.AppendLine("if(parameters!=null)"); codeString.AppendLine("{"); for (var i = 0; i < parameters.Length; i++) { codeString.AppendLine(string.Format("{0}=({1})parameters[{2}];", parameters[i].Name, this.GetProxyParameterName(parameters[i]), i)); } codeString.AppendLine("}"); if (isOut) { codeString.AppendLine("else"); codeString.AppendLine("{"); for (var i = 0; i < parameters.Length; i++) { if (parameters[i].IsOut) { codeString.AppendLine(string.Format("{0}=default({1});", parameters[i].Name, this.GetProxyParameterName(parameters[i]))); } } codeString.AppendLine("}"); } } if (isOut || isRef) { if (rpcMethod.HasReturn) { codeString.AppendLine(string.Format("return Task.FromResult<{0}>(returnData);", this.GetProxyParameterName(rpcMethod.Info.ReturnParameter))); } else { codeString.AppendLine(string.Format("return EasyTask.CompletedTask;")); } } codeString.AppendLine("}"); } return codeString.ToString(); } /// /// 获取接口的代理代码 /// /// /// public virtual string GetInterfaceProxyCode(RpcMethod rpcMethod) { var codeString = new StringBuilder(); var description = this.GetDescription(rpcMethod); var parameters = this.GetParameters(rpcMethod, out var isOut, out var isRef, out _); if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InterfaceSync)) { codeString.AppendLine("///"); codeString.AppendLine($"///{description}"); codeString.AppendLine("///"); foreach (var item in this.Exceptions) { codeString.AppendLine($"/// {item.Value}"); } codeString.Append(this.GetReturn(rpcMethod, false)); codeString.Append(' '); codeString.Append(this.GetMethodName(rpcMethod, false)); codeString.Append('(');//方法参数 for (var i = 0; i < parameters.Count; i++) { if (i > 0) { codeString.Append(','); } codeString.Append(parameters[i]); } if (parameters.Count > 0) { codeString.Append(','); } codeString.Append(this.GetInvokeOption()); codeString.AppendLine(");"); } if (this.GeneratorFlag.HasFlag(CodeGeneratorFlag.InterfaceAsync)) { codeString.AppendLine("///"); codeString.AppendLine($"///{description}"); codeString.AppendLine("///"); foreach (var item in this.Exceptions) { codeString.AppendLine($"/// {item.Value}"); } codeString.Append(this.GetReturn(rpcMethod, true)); codeString.Append(' '); codeString.Append(this.GetMethodName(rpcMethod, true)); codeString.Append('(');//方法参数 for (var i = 0; i < parameters.Count; i++) { if (i > 0) { codeString.Append(','); } codeString.Append(parameters[i]); } if (parameters.Count > 0) { codeString.Append(','); } codeString.Append(this.GetInvokeOption()); codeString.AppendLine(");"); } return codeString.ToString(); } /// /// 获取调用键 /// /// /// public virtual string GetInvokenKey(RpcMethod rpcMethod) { if (this.MethodInvoke) { return this.GetMethodName(rpcMethod, false); } else { return !this.InvokeKey.IsNullOrEmpty() ? this.InvokeKey : $"{rpcMethod.ServerFromType.FullName}.{rpcMethod.Name}".ToLower(); } } /// /// 获取调用配置 /// /// public virtual string GetInvokeOption() { return "IInvokeOption invokeOption = default"; } /// /// 获取生成的函数名称 /// /// /// /// public virtual string GetMethodName(RpcMethod rpcMethod, bool isAsync) { var name = string.IsNullOrEmpty(this.MethodName) ? rpcMethod.Name : this.MethodName.Format(rpcMethod.Name); return isAsync ? name + "Async" : name; } /// /// 获取参数生成 /// /// /// /// /// /// public virtual List GetParameters(RpcMethod rpcMethod, out bool isOut, out bool isRef, out ParameterInfo[] parameters) { var list = new List(); isOut = false; isRef = false; parameters = rpcMethod.GetNormalParameters().Select(a => a.ParameterInfo).ToArray(); for (var i = 0; i < parameters.Length; i++) { var codeString = new StringBuilder(); if (parameters[i].ParameterType.Name.Contains("&")) { if (parameters[i].IsOut) { isOut = true; codeString.Append(string.Format("out {0} {1}", this.GetProxyParameterName(parameters[i]), parameters[i].Name)); } else { isRef = true; codeString.Append(string.Format("ref {0} {1}", this.GetProxyParameterName(parameters[i]), parameters[i].Name)); } } else { codeString.Append(string.Format("{0} {1}", this.GetProxyParameterName(parameters[i]), parameters[i].Name)); } if (parameters[i].HasDefaultValue) { var defaultValue = parameters[i].DefaultValue; if (defaultValue == null) { codeString.Append(string.Format("=null")); } else if (defaultValue.ToString() == string.Empty) { codeString.Append(string.Format("=\"\"")); } else if (defaultValue.GetType() == typeof(string)) { codeString.Append(string.Format("=\"{0}\"", defaultValue)); } else if (defaultValue.GetType() == typeof(bool)) { codeString.Append(string.Format("={0}", defaultValue.ToString().ToLower())); } else if (typeof(ValueType).IsAssignableFrom(defaultValue.GetType())) { codeString.Append(string.Format("={0}", defaultValue)); } } list.Add(codeString.ToString()); } return list; } /// /// 从类型获取代理名 /// /// /// public virtual string GetProxyParameterName(ParameterInfo parameterInfo) { return this.ClassCodeGenerator.GetTypeFullName(parameterInfo); } /// /// 获取返回值 /// /// /// /// public virtual string GetReturn(RpcMethod rpcMethod, bool isAsync) { if (isAsync) { return rpcMethod.ReturnType == null ? "Task" : $"Task<{this.GetProxyParameterName(rpcMethod.Info.ReturnParameter)}>"; } else { return rpcMethod.ReturnType == null ? "void" : this.GetProxyParameterName(rpcMethod.Info.ReturnParameter); } } internal void SetClassCodeGenerator(ClassCodeGenerator classCodeGenerator) { this.ClassCodeGenerator = classCodeGenerator; } } }