您现在的位置是:首页 >

技术主管和技术总监的区别 详解.NET中的动态编译技术

火烧 2021-05-13 13:49:19 1083
详解.NET中的动态编译技术   代码的动态编译并执行是一个 NET平台提供给我们的很强大的工具用以灵活扩展(当然是面对内部开发人员)复杂而无法估算的逻辑 并通过一些额外的代码来扩展我们已有 的应用程

详解.NET中的动态编译技术  

  代码的动态编译并执行是一个 NET平台提供给我们的很强大的工具用以灵活扩展(当然是面对内部开发人员)复杂而无法估算的逻辑 并通过一些额外的代码来扩展我们已有 的应用程序 这在很大程度上给我们提供了另外一种扩展的方式(当然这并不能算是严格意义上的扩展 但至少为我们提供了一种思路)    动态代码执行可以应用在诸如模板生成 外加逻辑扩展等一些场合 一个简单的例子 为了网站那的响应速度 HTML静态页面往往是我们最好的选择 但基于数据驱动的网站往往又很难用静态页面实现 那么将动态页面生成的工作或许就是一个很好的应用场合 另外 对于一些模板的套用 我们同样可以用它来做 另外这本身也是插件编写的方式

  最基本的动态编译

技术主管和技术总监的区别 详解.NET中的动态编译技术

   Net为我们提供了很强大的支持来实现这一切我们可以去做的基础 主要应用的两个命名空间是 System CodeDom Compiler和Microsoft CSharp或Microsoft VisualBasic 另外还需要用到反射来动态执行你的代码 动态编译并执行代码的原理其实在于将提供的源代码交予CSharpCodeProvider来执行编译(其实和CSC没什么两样) 如果没有任何编译错误 生成的IL代码会被编译成DLL存放于于内存并加载在某个应用程序域(默认为当前)内并通过反射的方式来调用其某个方法或者触发某个事件等 之所以说它是插件编写的一种方式也正是因为与此 我们可以通过预先定义好的借口来组织和扩展我们的程序并将其交还给主程序去触发 一个基本的动态编译并执行代码的步骤包括

  · 将要被编译和执行的代码读入并以字符串方式保存

  · 声明CSharpCodeProvider对象实例

  · 调用CSharpCodeProvider实例的CompileAssemblyFromSource方法编译

  · 用反射生成被生成对象的实例(Assembly CreateInstance)

  · 调用其方法

  以下代码片段包含了完整的编译和执行过程

  //get the code to pile string strSourceCode = this txtSource Text; // Create a new CSharpCodePrivoder instance CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(); // Sets the runtime piling parameters

  by crating a new CompilerParameters instance CompilerParameters objCompilerParameters = new CompilerParameters(); objCompilerParameters ReferencedAssemblies Add( System dll ); objCompilerParameters ReferencedAssemblies Add( System Windows Forms dll ); objCompilerParameters GenerateInMemory = true; // CompilerResults: Complile the code snippet

  by calling a method from the provider CompilerResults cr = objCSharpCodePrivoder

  CompileAssemblyFromSource(objCompilerParameters

  strSourceCode); if (cr Errors HasErrors) { string strErrorMsg = cr Errors Count ToString() + Errors: ; for (int x = ; x < cr Errors Count; x++) { strErrorMsg = strErrorMsg + rnLine: + cr Errors[x] Line ToString() + + cr Errors[x] ErrorText; } this txtResult Text = strErrorMsg; MessageBox Show( There were build erros please modify your code

   Compiling Error ); return; } // Invoke the method by using Reflection Assembly objAssembly = cr CompiledAssembly; object objClass = objAssembly CreateInstance( Dynamicly HelloWorld ); if (objClass == null) { this txtResult Text = Error: + Couldn t load class ; return; } object[] objCodeParms = new object[ ]; objCodeParms[ ] = Allan ; string strResult = (string)objClass GetType() InvokeMember( GetTime BindingFlags InvokeMethod null objClass objCodeParms); this txtResult Text = strResult;

  需要解释的是 这里我们在传递编译参数时设置了GenerateInMemory为true 这表明生成的DLL会被加载在内存中(随后被默认引用入当前应用程序域) 在调用GetTime方法时我们需要加入参数 传递object类型的数组并通过Reflection的InvokeMember来调用 在创建生成的Assembly中的对象实例时 需要注意用到的命名空间是你输入代码的真实命名空间 以下是我们输入的测试代码(为了方便 所有的代码都在外部输入 动态执行时不做调整)

  using System; namespace Dynamicly { public class HelloWorld { public string GetTime(string strName) { return Wele + strName +

  Check in at + System DateTime Now ToString(); } } }

  运行附件中提供的程序 可以很容易得到一下结果

  
永远跟党走
  • 如果你觉得本站很棒,可以通过扫码支付打赏哦!

    • 微信收款码
    • 支付宝收款码