根据 Assembly 生成代码框架。
这是学习 AvalonEdit 的一个副产品。学习时,照着源代码新建文件夹,新建文件,添加方法与属性,虽然只是个框架,也要花费大量时间。为什么不让它自动生成呢?于是,新建了个控制台程序,一步步添加,一步步显示,一步步调整。虽然还有许多不完善的地方,但它基本能用了。将 Main 方法略作改动,便成了 Build 方法。为操作方便,加了个 WPF 界面。OK!下一步可参照 ILSpy 来进行改写,当也是一款不错的工具吧。限于时间与能力,暂且作罢。
主要代码如下:
[flash=500,400]http://s1.knowsky.com/20160211/q1scxu2qdpe18.gif[/flash][flash=500,400]http://s1.knowsky.com/20160211/2f5afdf2ao019.gif[/flash]1/**2*PRogram.cs (c) 2015 by x013*/4usingSystem;5usingSystem.Collections.Generic;6usingSystem.Diagnostics;7usingSystem.IO;8usingSystem.Linq;9usingSystem.Reflection;10usingSystem.Text;11usingSystem.Text.RegularExpressions;12usingSystem.Windows;1314namespacex01.CodeBuilder15{16publicclassTest<THllo>17{1819}20///<summary>21///Description of Program.22///</summary>23publicstaticclassBuildHelper24{25staticreadonlyStringBuilder sb =newStringBuilder();26staticreadonlyList<string> usings =newList<string>();27staticstringheaderFormat ="/**\n * {0}.cs (c) 2015 by x01\n */\n";2829///<summary>30///根据 Assebmly 生成代码框架。31///</summary>32///<param name="path">程序集路径名</param>33///<param name="outputDirectory">输出目录</param>34publicstaticvoidBuild(stringpath,stringoutputDirectory)35{36if(!File.Exists(path)) {37thrownewException("Assembly file not found.");38}39if(!Directory.Exists(outputDirectory)) {40Directory.CreateDirectory(outputDirectory);41}4243Assembly assembly =Assembly.LoadFile(path);44stringassemblyName = assembly.FullName.Split(',')[0];4546stringassemblyPath =Path.GetDirectoryName(assembly.Location);47foreach(vartypeinassembly.GetTypes()) {48usings.Clear();4950if(!(type.IsEnum || type.IsClass || type.IsInterface ||type.IsGenericType)) {51continue;52}5354stringtypeName = type.FullName.Replace(assemblyName +".","");5556string[] typeNameSplits = typeName.Split('.');57stringfileDirectory =outputDirectory;58if(typeNameSplits.Length >1) {59for(inti =0; i < typeNameSplits.Length -1; i++) {60fileDirectory +="\\"+typeNameSplits[i];61if(!Directory.Exists(fileDirectory)) {62Directory.CreateDirectory(fileDirectory);63}64}65}6667sb.Clear();68intlastDotIndex = type.FullName.LastIndexOf('.');69stringnamespaceName = lastDotIndex >0? type.FullName.Substring(0,lastDotIndex) : type.FullName;7071sb.Append("namespace"+ namespaceName +"\n{\n");7273stringconvertName =ConvertType(type.Name);74sb.Append("\t//TODO:"+ convertName +"\n");7576if(type.IsPublic) {77sb.Append("\tpublic");78}else{79sb.Append("\t");80}8182if(type.IsAbstract && !type.IsInterface) {83sb.Append("abstract");84}elseif(type.IsSealed && !type.IsEnum) {85sb.Append("sealed");86}8788if(type.IsEnum) {89sb.Append("enum");90}elseif(type.IsClass) {91sb.Append("class");92}elseif(type.IsInterface) {93sb.Append("interface");94}9596sb.Append(convertName);97if(type.BaseType !=null&& !string.IsNullOrEmpty(type.BaseType.Name)) {98sb.Append(":"+ConvertType(type.BaseType.Name));99}100sb.Append("\n\t{\n");101102varbaseProperties = type.BaseType !=null? type.BaseType.GetProperties() :newPropertyInfo[1];103foreach(varpropertyintype.GetProperties()) {104if(type.IsEnum)continue;105106varpropertyString =property.ToString();107boolskip =false;108foreach(varbpinbaseProperties) {109if(bp ==null)continue;110if(propertyString ==bp.ToString()) {111skip =true;112
break;113}114}115if(skip)continue;116117intlastIndex = propertyString.LastIndexOf('.');118stringpropu =string.Empty;119if(lastIndex >=0)120propu = propertyString.Substring(0,lastIndex);121propu =ConvertType(propu);122if(!usings.Contains(propu) && !string.IsNullOrEmpty(propu)) {123usings.Add(propu);124}125stringp = propertyString.Substring(lastIndex+1);126string[] ps = p.Split('');127ps[0] = ConvertType(ps[0]) +"";128p =string.Empty;129for(inti =0; i < ps.Length; i++) {130p +=ps[i];131}132sb.Append("\t\tpublic"+ p +"{ get; set; }\n");133}134135sb.Append("\n");136137varbaseMethods = type.BaseType !=null? type.BaseType.GetMethods() :newMethodInfo[1];138foreach(varmethodintype.GetMethods()) {139if(type.IsEnum)continue;140141boolskip =false;142foreach(varbminbaseMethods) {143if(bm ==null)
break;144if(bm.ToString() ==method.ToString()) {145skip =true;146
break;147}148}149if(skip)continue;150151vartypeString =method.ReturnType.ToString();152if(method.Name.Contains("get_") || method.Name.Contains("set_")153|| method.Name.Contains("add_") || method.Name.Contains("remove_")) {154continue;155}156intlastIndex = typeString.LastIndexOf('.');157stringr =string.Empty;158if(lastIndex >0) {159stringu = typeString.Substring(0,lastIndex);160u =ConvertType(u);161if(!usings.Contains(u) && !string.IsNullOrEmpty(u)) {162usings.Add(u);163}164r = typeString.Substring(lastIndex+1);165}else{166r =typeString;167}168r =ConvertType(r);169sb.Append("\t\tpublic"+ r +""+ method.Name +"(");170intpcount =method.GetParameters().Length;171intcount =0;172foreach(varparameterinmethod.GetParameters()) {173varparamString =parameter.ParameterType.ToString();174intplast = paramString.LastIndexOf('.');175stringptype =string.Empty;176if(plast >0) {177stringpu = paramString.Substring(0, plast);178pu =ConvertType(pu);179if(!usings.Contains(pu)) {180usings.Add(pu);181}182ptype = paramString.Substring(plast+1);183}else{184ptype =paramString;185}186ptype =ConvertType(ptype);187count ++;188if(pcount ==1|| pcount ==count)189sb.Append(ptype +""+parameter.Name);190else191sb.Append(ptype +""+ parameter.Name +",");192}193sb.Append(")\n");194sb.Append("\t\t{\n\t\t\tthrow new NotImplementedException();\n\t\t}\n");195}196197sb.Append("\t}\n");//end type198199sb.Append("}");//end namespace200201stringheader =string.Format(headerFormat, convertName);202stringustring =header;203foreach(varusinusings) {204ustring +="using"+ us +";\n";205}206ustring +="\n"+sb.ToString();207208if(!string.IsNullOrEmpty(convertName)) {209stringfilename = Path.Combine(fileDirectory, convertName) +".cs";210File.WriteAllText(filename, ustring);211}212}213}214215staticstringConvertType(stringtypeName)216{217intindex = typeName.IndexOf('`');218if(index >=0)219typeName = typeName.Substring(0,index);220index = typeName.IndexOf('+');221if(index >=0)222typeName = typeName.Substring(0,index);223index = typeName.IndexOf('<');224if(index >=0)225typeName = typeName.Substring(0,index);226index = typeName.IndexOf(']');227if(index >=0)228typeName = typeName.Substring(0, index);229230switch(typeName) {231case"Boolean":232return"bool";233case"Void":234return"void";235case"Int32":236return"int";237case"Object":238return"object";239case"Double":240return"double";241case"String":242return"string";243case"Long":244return"long";245default:246
break;247}248249returntypeName;250}251252//测试用的。253//static void Main(string[] args)254//{255//string path = @"E:\Temp\Lab\x01\x01.CodeBuilder\bin\Debug\x01.MelonEdit.exe";256//string target = @"E:\Temp\Lab\x01\Output";257//Build(path,target);258//259//Console.ReadKey(true);260//}261}262}
View Code
看一看,真是惨不忍睹。这大概就是所谓的意大利面条吧。
源代码下载:https://github.com/chinax01/x01.CodeBuilder