通过字符串动态创建类对象
功能的需求是 不需要使用IOC 框架 来对创建指定对象。
.NET 中 要想动态的 创建对象 做耦合 好像只能做到 将类生成DLL 后 然后 加载DLL 接着创建对象。
JAVA 当个类文件 就可以运行。
希望做到 当读一个 .class 或者 .TXT 就可以 动态创建类对象 那多好啊!!! 还可以将 类文件 以字符串的形式写到 数据库中 通过数据库来 创建类对象。
然后就各种百度 谷歌 贴吧等 找有没相关的 解决方案 还好 找到了 。 不藏着 分享出来
代码很简单:
CSharpCodeProvider p = new CSharpCodeProvider(); CompilerParameters param = new CompilerParameters(); string s = "public class AAA{ public string name;}"; CompilerResults rel = p.CompileAssemblyFromSource(param, s); Type t = rel.CompiledAssembly.GetType("AAA"); object o = t.GetConstructor(System.Type.EmptyTypes).Invoke(null); string sdc = t.GetField("name").GetValue(o).ToString(); Console.WriteLine(t.GetField("name").GetValue(o).ToString());
下面是 我做的详解 和 性能时间
new AAA(); // new 一个 AAA 的时间是 0.3314 毫秒 Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); // 开始监视代码运行时间 // 是编译器 类 CompilerParameters param = new CompilerParameters(); //param.OutputAssembly = "myTest.dll";// 设置生成的程序集名称 EXE还是DLL 执行设置后缀 param.GenerateInMemory = true; // 是否写入到内存中 而不是磁盘 写入内存 程序集名称设置无效 param.IncludeDebugInformation = false; //是否在已编译的可执行文件中包含调试信息。 // 设置生成的文件地址。 false 是表示不生成详细文件 只生成一个DLL 或EXE //param.TempFiles = new TempFileCollection(".", false); string s = " public class AAA { public string name;}"; // 通过CSharpCodeProvider 从包含源代码的字符串的指定数组(params string[]),使用指定的编译器设置编译程序集 // 也就是通过 改类 来创建一个DLL // 构造类型 提供对 C# 代码生成器和代码编译器的实例的访问 CompilerResults rel = null; using (CSharpCodeProvider p = new CSharpCodeProvider()) rel = p.CompileAssemblyFromSource(param, s); stopwatch.Stop(); // 停止监视 TimeSpan timespan = stopwatch.Elapsed; Console.WriteLine(timespan.TotalMilliseconds);// 170 毫秒 var sdsd = param.TempFiles;// 获取或设置包含临时文件的集合 可以看生成文件到哪里了 // 直接获取创建的类型 Type t = rel.CompiledAssembly.GetType("AAA"); // 获取全部类型 Type[] tsTypes = rel.CompiledAssembly.GetTypes(); // try 一下 保证不会出现空引用 // 本地程序集中没有 需要使用对象的 引用程序集 用反射来 赋值 调用方法 object o = t.GetConstructor(System.Type.EmptyTypes).Invoke(null); Stopwatch stopwatch1 = new Stopwatch(); stopwatch1.Start(); // 开始监视代码运行时间 t.GetField("name").SetValue(o, "1"); // 1毫秒 t.GetField("name").GetValue(o); // 1毫秒 stopwatch1.Stop(); // 停止监视 TimeSpan timespan1 = stopwatch1.Elapsed; Console.WriteLine(timespan1.TotalMilliseconds); Console.WriteLine(t.GetField("name").GetValue(o).ToString());
希望 哪位大神 有更高效 的 方式 可以告诉本人一下哈 。。