Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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());
        }