反射发出应用程序应用场景
本节更加详细地介绍应用程序使用反射发出和动态方法的一些方案。
在 Web 浏览器中执行脚本
在此方案中,Web 浏览器加载包含脚本程序的 HTML 页并执行此程序。 步骤如下所示:
Web 浏览器在 Web 浏览器的应用程序域中启动脚本引擎。
Web 浏览器从 HTML 页展开脚本并将它传递到脚本引擎。
脚本引擎创建瞬态动态程序集。
脚本引擎使用反射发出 API 将代码发出到动态程序集中。
在 ASP.NET 页中执行脚本
在此方案中,浏览器打开包含脚本程序的 ASP.NET 页。 该程序在服务器上编译并执行。 步骤如下所示:
ASP.NET 启动它的应用程序域并启动脚本引擎以编译和执行程序。
脚本引擎创建持久动态程序集和该动态程序集中的持久动态模块。
脚本引擎使用反射发出 API 编译程序并将代码发出到持久动态模块中。
编译的代码会运行并遇到 eval 表达式。
脚本引擎在动态程序集中创建瞬态动态模块以包含 eval 表达式的代码。
脚本引擎通过执行瞬态动态模块来计算 eval 表达式。
ASP.NET 请求脚本引擎将动态程序集和持久动态模块保存在缓存中,以便当此页被再次访问时不需要重新编译脚本。
使用反射发出编译正则表达式
在此方案中,编译器使用反射发出编译源代码中的正则表达式。 用户可以声明应编译哪个正则表达式。 步骤如下所示:
编译器处理用户源代码中正则表达式的第一次使用。
由于用户已请求编译表达式,编译器使用反射发出将正则表达式编译为自定义扫描仪类。 正则表达式首先被翻译为编译器的正则表达式操作码。 例如,一个指令可能指示“尝试匹配零个或多个 a”。正则表达式操作码然后将转换为 Microsoft 中间语言 (MSIL)。 例如,编译器可能生成一个循环,以循环访问它发现的所有字母匹配项。
编译器保存已编译的扫描仪类供将来使用。
编译器实例化已编译的扫描仪类并在当前应用程序域中执行代码。
编译器处理用户源代码中同一正则表达式的后续使用。
编译器在已编译的扫描仪类中检索正则表达式,将其实例化并在当前应用程序域中执行代码。
当使用正则表达式的第一个实例时,由于编译器需要将表达式编译为扫描仪类,用户会招致性能损失。 不过,对同一正则表达式的后续使用会有效地执行。 对于常用的正则表达式,一次性编译损失无关紧要,这是因为执行时可能有显著改进。