• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >ASP.NET > .NET 动态编译

.NET 动态编译

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-11

通过本文主要向大家介绍了如何用vb.net动态编译,f3322.net动态域名,nvdvr.net 动态域名,vb.net 动态数组,vb.net动态添加控件等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
这在很大程度上给我们提供了另外一种扩展的方式(当然这并不能算是严格意义上的扩展,但至少为我们提供了一种思路)。

动态代码执行可以应用在诸如模板生成,外加逻辑扩展等一些场合。一个简单的例子,为了网站那的响应速度,HTML静态页面往往是我们最好的选择,但基于数据驱动的网站往往又很难用静态页面实现,那么将动态页面生成html的工作或许就是一个很好的应用场合。另外,对于一些模板的套用,我们同样可以用它来做。另外这本身也是插件编写的方式。

 

最基本的动态编译

 

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

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

·         声明CSharpCodeProvider对象实例

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

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

·         调用其方法

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

//get the code to compile

string strSourceCode = this.txtSource.Text;

 

// 1.Create a new CSharpCodePrivoder instance

CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();

 

// 2.Sets the runtime compiling 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;

 

// 3.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 = 0; x < cr.Errors.Count; x++)

    {

        strErrorMsg = strErrorMsg + "\r\nLine: " +

                     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;

}

 

// 4. 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[1];

objCodeParms[0] = "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  "Welcome " + strName + ", Check in at " + System.DateTime.Now.ToString();

        }

    }

}

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

 

改进的执行过程

 

现在一切看起来很好,我们可以编译代码并把代码加载到当前应用程序域中来参与我们的活动,但你是否想过去卸载掉这段程序呢?更好的去控制程序呢?另外,当你运行这个程序很多遍的时候,你会发现占用内存很大,而且每次执行都会增大内存使用。是否需要来解决这个问题呢?当然需要,否则你会发现这个东西根本没用,我需要执行的一些大的应用会让我的服务器crzay,不堪重负而疯掉的。

要解决这个问题我们需要来了解一下应用程序域。.NET Application Domain是.NET提供的运行和承载一个活动的进程(Process)的容器,它将这个进程运行所需的代码和数据,隔离到一个小的范围内,称为Application Domain。当一个应用程序运行时,Application Domains将所有的程序集/组件集加载到当前的应用程序域中,并根据需要来调用。而对于动态生成的代码/程序集,我们看起来好像并没有办法去管理它。其实不然,我们可以用Application Domain提供的管理程序集的办法来动态加载和移除Assemblies来达到我们的提高性能的目的。具体怎么做呢,在前边的基础上增加以下步骤:

·         创建另外一个Application Domain

·         动态创建(编译)代码并保存到磁盘

·         创建一个公共的远程调用接口

·         创建远程调用接口的实例。并通过这个接口来访问其方法。

换句话来讲就是将对象加载到另外一个AppDomain中并通过远程调用的方法来调用。所谓远程调用其实也就是跨应用程序域调用,所以这个对象(动态代码)必须继承于MarshalByRefObject类。为了复用,这个接口被单独提到一个工程中,并提供一个工厂来简化每次的调用操作:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Reflection;

 

namespace RemoteAccess

{

&nb

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • .NET 动态编译

相关文章

  • 2017-05-11蛇年多屏图片切换(可添加图片链接以及编辑标题)
  • 2017-05-11关闭子页面刷新父页面中部分控件数据的方法
  • 2017-05-11System.Web.Routing入门及进阶
  • 2017-05-11asp.net的公共变量声明问题(解决)
  • 2017-05-11ASP.NET数据库编程之处理文件访问许可
  • 2017-05-11asp.net学习中发现的比较完整的流程
  • 2017-05-11asp.net ajaxControlToolkit FilteredTextBoxExtender的简单用法
  • 2017-05-11asp.net实现图片以二进制流输出的两种方法
  • 2017-05-11asp.net中将数据库绑定到DataList控件的实现方法与实例代码
  • 2017-05-11.net 中的SqlConnection连接池机制详解

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • ASP.NET Gridview与checkbox全选、全不选实现代码
    • .NET建造者模式讲解
    • LINQ字符串向datetime 转换时失败的处理方法
    • ASP.NET中上传并读取Excel文件数据示例
    • 为T-SQL添加intellisense功能
    • ASP.NET中操作数据库的基本步骤分享
    • asp.net线程批量导入数据时通过ajax获取执行状态
    • 将.aspx转换为.htm的两种方法
    • ASP.NET 定制简单的错误处理页面实现代码
    • asp.net中url字符串编码乱码的原因与解决方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有