/// <summary> /// 模板数据生成 /// </summary> /// <param name="types"></param> /// <returns></returns> internal static TemplateMetadata BuildTemplate(Type[] types) { var template = new TemplateMetadata(); template.UsingList.Add(typeof(object).Namespace); template.UsingList.Add(typeof(Thread).Namespace); template.UsingList.Add(typeof(Task).Namespace); template.UsingList.Add(typeof(IHttpService).Namespace); template.UsingList.Add(typeof(HttpServiceAttribute).Namespace); template.UsingList.Add(typeof(HttpClientWrapperExtension).Namespace); foreach (var type in types) { var classTemplate = new ClassTemplate() { InterfaceType = type, Namespace = $"Dynamic.{RandomName()}", Name = $"AutoGenerated{type.Name.TrimStart('I').Replace("`", string.Empty)}" }; classTemplate.UsingList.Add(type.Namespace); //类标签 foreach (var attr in CustomAttributeData.GetCustomAttributes(type)) { classTemplate.AttributeList.Add(new CustomAttributeTemplate(attr).ToString()); } //泛型类信息收集 if (type.IsGenericType) { foreach (var argumentType in type.GetGenericArguments()) { var argument = new GenericArgumentTemplate() { Name = argumentType.Name }; classTemplate.GenericArguments.Add(argument); if (argumentType.GenericParameterAttributes == GenericParameterAttributes.None && argumentType.GetGenericParameterConstraints().Length == 0) { continue; } //class约束 if (argumentType.GenericParameterAttributes.HasFlag(GenericParameterAttributes.ReferenceTypeConstraint)) { argument.Constraints.Add("class"); } //值类型约束 if (argumentType.GenericParameterAttributes.HasFlag(GenericParameterAttributes.NotNullableValueTypeConstraint)) { argument.Constraints.Add("struct"); } //类型约束 foreach (var constraintType in argumentType.GetGenericParameterConstraints()) { argument.Constraints.Add(new TypeTemplate(constraintType).ToString()); } //无参构造函数 if (argumentType.GenericParameterAttributes.HasFlag(GenericParameterAttributes.DefaultConstructorConstraint)) { argument.Constraints.Add("new()"); } } } //方法信息 foreach (var method in type.GetRuntimeMethods()) { if (method.IsSpecialName) { continue; } classTemplate.MethodList.Add(new MethodTemplate(method)); } //属性 foreach (var property in type.GetRuntimeProperties()) { if (property.IsSpecialName) { continue; } classTemplate.PropertyList.Add(new PropertyTemplate(property)); } //todo:不支持事件 template.ClassList.Add(classTemplate); } return(template); }
/// <summary> /// 组装代码 /// </summary> /// <param name="template"></param> /// <returns></returns> internal static string GenerateCode(TemplateMetadata template) { StringBuilder builder = new StringBuilder(2048); foreach (var @using in template.UsingList) { builder.AppendFormat("using {0};", @using).AppendLine(); } builder.AppendLine(); foreach (var @class in template.ClassList) { int indentLevel = 0; //缩进级别 builder.Append($"namespace ").Append(@class.Namespace).AppendLine(); builder.Append("{").AppendLine(); indentLevel++; foreach (var classUsing in @class.UsingList) { builder.AppendIndent(indentLevel).AppendFormat("using {0};", classUsing).AppendLine(); } builder.AppendLine(); //创建类 builder.AppendIndent(indentLevel).Append("/*").AppendLine(); builder.AppendIndent(indentLevel).Append(" *").AppendFormat(" {0} implement {1}", @class.Name, new TypeTemplate(@class.InterfaceType).Name).AppendLine(); builder.AppendIndent(indentLevel).Append(" */").AppendLine(); foreach (var classAttr in @class.AttributeList) { builder.AppendIndent(indentLevel).Append(classAttr).AppendLine(); } builder.AppendIndent(indentLevel).Append("public class ").Append(@class.Name); var genericArg = string.Join(",", @class.GenericArguments.Select(x => x.Name)); if (!string.IsNullOrEmpty(genericArg)) { builder.AppendFormat("<{0}>", genericArg); } //接口实现 builder.Append(" : "); builder.Append(new TypeTemplate(@class.InterfaceType).Name); if (!string.IsNullOrEmpty(genericArg)) { builder.AppendFormat("<{0}>", genericArg); } //泛型约束 foreach (var argument in @class.GenericArguments) { builder.AppendFormat(" where {0} : {1}", argument.Name, string.Join(",", argument.Constraints)); } builder.AppendLine(); builder.AppendIndent(indentLevel).Append('{').AppendLine(); indentLevel++; //私有字段 builder.AppendIndent(indentLevel).Append("private readonly IRequestDescriptorBuilder _builder;").AppendLine(); builder.AppendIndent(indentLevel).Append("private readonly IHttpClientWrapper _client;").AppendLine(); builder.AppendLine(); //---构造函数----- builder.AppendIndent(indentLevel).Append("public ").Append(@class.Name).Append("(IRequestDescriptorBuilder builder, IHttpClientWrapper client)") .AppendLine(); builder.AppendIndent(indentLevel).Append('{').AppendLine(); indentLevel++; builder.AppendIndent(indentLevel).Append("_builder = builder;").AppendLine(); builder.AppendIndent(indentLevel).Append("_client = client;").AppendLine(); indentLevel--; builder.AppendIndent(indentLevel).Append('}').AppendLine(); //--构造函数结束----- builder.AppendLine(); //---属性开始--- foreach (var property in @class.PropertyList) { builder.AppendLine(); builder.AppendIndent(indentLevel).Append(property.ToString()).AppendLine(); } //---属性结束--- //----方法开始---- foreach (var method in @class.MethodList) { builder.AppendLine(); builder.AppendIndent(indentLevel).Append("// ").Append(method.Name).AppendLine(); //方法标签 foreach (var methodAttr in method.AttributeList) { builder.AppendIndent(indentLevel).Append(methodAttr).AppendLine(); } //方法签名 builder.AppendIndent(indentLevel).Append("public "); if (method.IsAsync) { builder.Append("async "); } builder.Append(method.ReturnType.ToString()).Append(" "); builder.Append(method.Name); if (method.GenericArguments.Count > 0) { builder.AppendFormat("<{0}>", string.Join(",", method.GenericArguments.Select(x => x.Name))); } builder.Append("("); builder.Append(string.Join(",", method.Parameters)); builder.Append(")"); //方法泛型约束 foreach (var argument in method.GenericArguments) { builder.AppendFormat(" where {0} : {1}", argument.Name, string.Join(",", argument.Constraints)); } builder.AppendLine(); //---方法签名结束 builder.AppendIndent(indentLevel).Append("{").AppendLine(); indentLevel++; //---方法体开始----- //var request = _builder.Build(typeof(ITokenService), token, template); builder.AppendIndent(indentLevel).AppendFormat("var request = _builder.Build(this.GetType(),{0});", string.Join(",", method.Parameters.Select(x => x.Name))); builder.AppendLine(); //获取token变量 var tokenParam = method.Method.GetParameters().LastOrDefault(x => x.ParameterType == typeof(CancellationToken)); var tokenName = tokenParam != null ? method.Parameters.ToArray()[tokenParam.Position].Name : "CancellationToken.None"; builder.AppendIndent(indentLevel).Append(ClientInvokeCode(method.ReturnType.Type, tokenName)).AppendLine(); //---方法体结束----- indentLevel--; builder.AppendIndent(indentLevel).Append("}").AppendLine(); } //--方法结束-- indentLevel--; builder.AppendIndent(indentLevel).Append('}').AppendLine(); //--类结束-- indentLevel--; builder.AppendIndent(indentLevel).Append("}").AppendLine().AppendLine(); //--命名空间结束-- } return(builder.ToString()); }