玩转动态编译(四) 封装2014-03-20 cnblogs 冰麟轻武既然要使用动态编译,那么为他封装一个调用类,在调用时省去大量不必要的编码操作还是很有必要的 。为什么要封装?其实这个说起来很简单,就是发现现有的动态编译类在使用过程中显 得并不是那么好用。我觉得我可以让他变的更易使用。所以我应该重新封装了一个 DynamicCompile类。不过在这之前我还要考虑一下一个问题:我需要什么?在使 用动态编译的过程中,我逐渐的发现,动态编译有以下几种情况1.我拼接了一个静态类的代码, 需要返回这个类的类型2.我拼接了一个拥有无参构造函数的类的代码,需要返回这个类的实例3.我拼接了一个方法代码,需要返回这个方法的委托对于之前的DynamicCompile_1来说 ,我要完成这3个工作都需要额外的编写一些重复的,不必要的代码,这对我来说是一件令我很烦躁的事所以我想要3个方法代替他们
Type type = CompileClass("public static classaaa { public static User GetUser() { new User(); } }", usingTypes);object obj = CompileObject("public class bbb : ICloneable { public object Clone() { return new User(); } }", usingTypes);Func<object, string> func = CompileMethod<Func<object, string>>("public object GetUser() { return new User(); }", usingTypes);
封装先来看看现在的类
using Microsoft.CSharp;using System;using System.CodeDom.Compiler;using System.Collections.Generic;using System.Reflection;using System.Text;namespace blqw{public class DynamicCompile_1{/// <summary>/// /// </summary>/// <param name="code">需要编译的C#代码</param>/// <param name="usingTypes">编译代码中需要引用的类型</param>/// <returns></returns>public static Assembly CompileAssembly(string code, params Type[] usingTypes){CompilerParameters compilerParameters = new CompilerParameters();//动态编译中使用的参数对象compilerParameters.GenerateExecutable = false;//不需要生成可执行文件compilerParameters.GenerateInMemory = true;//直接在内存中运行//添加需要引用的类型HashSet<string> ns = new HashSet<string>();//用来保存命名空间,foreach (var type in usingTypes){ns.Add("using " + type.Namespace + ";" + Environment.NewLine);//记录命名空间,因为不想重复所以使用了HashSetcompilerParameters.ReferencedAssemblies.Add(type.Module.FullyQualifiedName);//这个相当于引入dll}code = string.Concat(ns) + code;//加入using命名空间的代码,即使原来已经有了也不会报错的//声明编译器using (CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider()){//开始编译CompilerResults cr = objCSharpCodePrivoder.CompileAssemblyFromSource(compilerParameters, code);if (cr.Errors.HasErrors)//如果有错误{StringBuilder sb = new StringBuilder();sb.AppendLine("编译错误:");foreach (CompilerError err in cr.Errors){sb.AppendLine(err.ErrorText);}throw new Exception(sb.ToString());}else{//返回已编译程序集return cr.CompiledAssembly;}}}}}DynamicCompile_1