星期三 十二月 16, 2009 23:28

cSharp动态调用和反射的一个绝佳例子

Posted by 邵 明博

之前看反射那一章,真把个人看郁闷了。不巧的是,看到很多业内人士的专业博客说,不会这个也搞了几年的项目开发。哎。顿时打消了学习这个知识的念头。不过,挺巧的是,今天又遇到了一个讲这个内容的章节,只不过内容更具体了。

这样一个动态调用的程序,貌似实现了一个编译器的功能。在Textbox里写上代码,能在程序下方看到编译结果。有趣的是,当代码出错的时候,能在程序中看到错误信息:

dynamic loading assemblies cSharp动态调用和反射的一个绝佳例子

//核心代码
       public string ComplieAndRun(string input,out bool hasError)
        {
            CompilerResults cResults = null;
            string returnData = null;
            hasError = false;

            using(Microsoft.CSharp.CSharpCodeProvider provider =new CSharpCodeProvider())
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(prefix);
                sb.Append(input);
                sb.Append(postfix);

                CompilerParameters option = new CompilerParameters();
                option.GenerateInMemory = true;
                cResults=provider.CompileAssemblyFromSource(option, sb.ToString());

            }

            if (cResults.Errors.HasErrors)
            {
                hasError = true;
                StringBuilder errMessage = new StringBuilder();
                foreach (CompilerError err in cResults.Errors)
                {
                    errMessage.AppendFormat("{0}:{1}", err.Line, err.ErrorText);
                }
                returnData = errMessage.ToString();
            }
            else
            {
                TextWriter temp=Console.Out;
                StringWriter sw = new StringWriter();
                Console.SetOut(sw);

                Type myType = cResults.CompiledAssembly.GetType("myDriver");
                myType.InvokeMember("Run", BindingFlags.InvokeMethod|BindingFlags.Public | BindingFlags.Static, null, null, null);

                Console.SetOut(temp);

                returnData = sw.ToString();
            }

            return returnData;
        }
    }

    //每次动态调用后,通过应用程序域卸载掉
    public class DynamicRunAppInDomain
    {
        public string CompileAndRun(string input,out bool hasErr)
        {
            AppDomain app = AppDomain.CreateDomain("DynamicRun");
            DynamicRun dr = (DynamicRun)app.CreateInstanceAndUnwrap("ShaoMingboDrive", "WpfApplication1.DynamicRun");
            string res = dr.ComplieAndRun(input,out hasErr);
            AppDomain.Unload(app);
            return res;

        }
    }

这里是一个该程序的二进制文件:动态调用demo (55).net framework 3.5 required
如果您的机器上没有安装.net,不妨下载这个打包好的文件:动态调用Setup (56)

Comment Form

calendar

2009年十二月
« 十一   二 »
 123456
78910111213
14151617181920
21222324252627
28293031  

最近评论