在前面章节中,笔者使用了反射和动态编译技术实现了快速ORM框架,在本章中笔者将继续使用这些技术来实现一个源自VB,是动态语言,它在编译时不会严格的检查对象的类型及其成员信息,执行后期绑定,而是在运行时检查,若运行时发现对象类型和成员信息错误,则会报运行时错误。脚本技术应当非常灵活和自由,袁某人觉得此时使用C#这种静态语言不是明智之举,而应当使用类似集成开发环境也有VBA宏的功能。脚本提供给应用系统二次开发的能力,而且这种二次开发能力简单灵活,部署方便。
在应用方面脚本技术带来的最大好处就是简单灵活,部署方便。脚本代码以纯文本的格式进行存储,修改方便,而且脚本修改后,应用系统无需重新启动而能立即使用新的脚本,脚本代码中能实现比较复制的逻辑控制,能响应应用系统的事件,能一定程度上扩展应用系统的功能,这有点类似数据库中的存储过程。
但脚本功能运行在应用系统提供的容器环境中,其功能是受到严格限制的,一些脚本还受到系统权限的限制。因此脚本只能有限的扩展应用系统的功能,若所需功能比较复杂,脚本可能无法实现,此时还得依赖传统编程。不过在很多情况下,脚本还是能发挥很大的作用。【袁永福原创,转载请注明出处】
脚本就是采用集成开发环境提供的宏也是采用框架提供了一个脚本引擎,那就是在程序集框架框架脚本,而是使用动态编译技术来实现脚本引擎。
使用动态编译技术实现脚本引擎设计
这里笔者将用倒推法来设计代码编译生成的是一个.NET程序集类库,为了方便起见,笔者将所有的脚本类型。笔者将脚本方法定义为静态方法,主要有两个好处,首先脚本引擎不必生成对象实例,其次能避免由于没有生成对象实例而导致的空引用错误,这样能减少脚本引擎的工作量。
SubName()”的语法的模块的概念。在模块的概念就能解决了这个问题。
在一些脚本中笔者经常可以看见类似“中直接使用“的一个语法特性。在框架编译器会认为附加了该特性的类型的静态属性值就是全局对象。比如笔者定义了一个GlobalObject类型,附加了StandardModuleAttribute特性,它有一个名为Document的静态属性,在对于脚本中的“编译器会针对“document”标识符检索所有附加了StandardModuleAttribute的类型的静态属性,最后命中GlobalObject类型,于是会自动扩展为“语法更适合作为脚本的语法。
类似全局对象,在中可以在任何时候任何地方直接使用,框架自带框架安装目录下的编译器的路径是“C:"WINDOWS"编译的命令行的说明,它支持一个名为“imports”的命令行参数指令。比如可以这样调用编译器命令行中使用imports指令和在编译器不会感知到该类型中定义的全局对象和全局函数,因此在编写编译器的命令行参数中使用“/imports:的全局对象和全局函数了。
根据上述说明,笔者设计如下的参与动态编译的代码
'脚本引擎使用的动态编译技术,而动态编译技术的第一个部分就是代码生成器,脚本大部分代码都是由主程序提供的,因此其代码生成器也就是将原始的脚本代码进行一些封装而已。【袁永福原创,转载请注明出处】
根据上述对运行时脚本的设计,用户可以导入其他的名称空间,于是脚本引擎定义了SourceImports属性来自定义导入的名称空间,定义该属性的代码如下
/// 源代码中使用的名称空间导入
/// 源代码中使用的名称空间导入
在脚本引擎的初始化过程中,程序会默认添加上System和脚本的Imports语句。然后输出Namespace和Module代码块来包括了用户提供的原始代码文本。这里的strSourceText就是用户提供的原始代码文本。最后变量
strRuntimeSource中就包含了实际运行的脚本代码文本后就可以编译了,为了提高效率,这里袁某定义了一个静态myAssemblies的哈希列表变量,定义该变量的代码如下
该列表缓存了以前编辑生成的程序集,键值就是脚本文本,键值就是程序集。若缓存区中没有找到以前缓存的程序集那脚本引擎就可以调用编译器参数
/// 引用的名称列表
Service程序使用的脚本调用这些属性将不会产生任何效果。对于WinForm程序,运行脚本前应当将主窗体设置到window全局对象的ParentWindow属性上。
Window全局对象还定义了一些函数用于显示一些消息对话框实现用户互换。主要代码为
/// 将对象转化为用于显示的文本
/// 显示错误消息框
在窗体的加载事件中我们初始化脚本引擎,其代码为
这里程序首先创建了一个名为myVBAEngine的脚本引擎对象,然后向它的VBCompilerImports列表添加了全局对象容器类型所在的名称空间脚本。该脚本代码为
sub 显示当前使用的脚本代码()
sub 在标题栏显示移动字幕()
在实际开发中,开发人员可以将XVBAEngine等C#代码拷贝到应用程序中即可添加脚本功能,也可以将修改本C#工程的属性使其单独编译成一个DLL然后供其他.NET程序使用。部署起来非常方便。
在本次课程中,笔者使用动态编译技术实现了等等都具有二次开发用的VBA脚本技术,使用本课程介绍的知识我们也可以为应用系统配置功能强大的脚本引擎,这能比较大的提高应用系统的灵活性。脚本引擎技术是一个非常实用的软件开发技术,值得推广。