在.NET中嵌入IronPython 交互

简介: 随着IronPyhon 2.0 的发布,.NET Dynamic Language Runtime 也更加成熟了,在2.0中我们可以用动态脚本以粘合剂的方式编写架构体系中的各种逻辑单元,既便于修改,又能灵活适合多变的业务场景。

随着IronPyhon 2.0 的发布,.NET Dynamic Language Runtime 也更加成熟了,在2.0中我们可以用动态脚本以粘合剂的方式编写架构体系中的各种逻辑单元,既便于修改,又能灵活适合多变的业务场景。当然,我的目标是在 Platform Framework 中能嵌入脚本引擎,而不是用 ipy.exe 去执行一个 "独立" 的任务。要让.net 项目能真正跟脚本进行交互,还得需要提供脚本引擎的实现。这得提到DLR一些基本 概念了。

下图摘自 DLR 帮助文件,通过它我们基本可以了解基于 DLR 的组成方式。

uploads/200812/18_155159_1.png

下图描述了 DLR 的基本执行流程。

uploads/200812/18_155213_2.png

  • ScriptRuntime: 创建 DLR 运行环境,这是整个执行过程的起始点,它表示一个全局的执行状态(比如程序集引用等等)。每个应用程序域(AppDomain)中可以启动多个 ScriptRuntime。
  • ScriptScope: 构建一个执行上下文,其中保存了环境及全局变量。宿主(Host)可以通过创建不同的 ScriptScope 来提供多个数据隔离的执行上下文。
  • ScriptEngine: DLR 动态语言(比如 IronPython) 执行类,可于解析和执行动态语言代码。
  • ScriptSource: 操控动态语言代码的类型,我们可以编译(Compile)、读取(Read Code Lines)或运行(Execute)代码。
  • CompiledCode: 调用 ScriptSource.Compile() 将源代码编译成 CompiledCode,这样多次执行就无需重复编译,从而提高执行性能。
  • ObjectOperations: 提供了相关方法,允许我们在宿主(Host)中操作 DLR 对象成员(Member)。

 现在我们来构建脚本引擎

当然我们必须加入IronPyhton提供的相关引用并导入命名空间

using IronPython.Hosting;
using IronPython.Compiler;
using IronPython.Runtime;
using Microsoft.Scripting;
using System.Runtime.Remoting;

  1. Hello World
    img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
    var py = @"
    def test():
    return ‘hello world~!’;
    print test();
    ";
    var engine 
    = Python.CreateEngine();
    var code 
    = engine.CreateScriptSourceFromString(py, SourceCodeKind.Statements);
    code.Execute();
    输出: hello world~!
    注意:Python 对于源代码缩进的格式有严格要求。
  2. 给Python上下文提供变量
    var scope = engine.Runtime.Globals; //engine.Runtime.CreateScope();
    scope.SetVariable("x", 123);
  3. 读取Python上下文中的变量
    var x = scope.GetVariable<int>("x");
    可以看出 ScriptScope 可以在 Host 和 ScriptRuntime 间传递数据。
  4. 对象实例共享
    img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
    var py = @"
    o.X = o.X + 2;
    print o.X;
    ";
    var engine 
    = Python.CreateEngine();
    var code 
    = engine.CreateScriptSourceFromString(py, SourceCodeKind.Statements);
    var scope 
    = engine.Runtime.Globals;
    var o 
    = new Data { X = 123 };
    scope.SetVariable(
    "o", o);
    code.Execute(scope);
    Console.WriteLine(o.X);
    载入程序集并由ScriptRuntime管理
  5. 创建程序集test.dll

    namespace  My.Library
    {
      
    public   class  MyClass
      {
        
    public   int  Test( int  x)
        {
          
    return   ++ x;
        }
      }

    创建Host程序

    img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
    var py = @"
    import clr;
    from My.Library import MyClass;
    from System import Console;
    o = MyClass();
    x.X = o.Test(x.X);
    Console.WriteLine(x.X);
    ";
    var engine 
    = Python.CreateEngine();
    engine.Runtime.LoadAssembly(Assembly.GetAssembly(
    typeof(int))); // mscorlib.dll
    engine.Runtime.LoadAssembly(Assembly.LoadFrom("test.dll")); // test.dll
    var code = engine.CreateScriptSourceFromString(py, SourceCodeKind.Statements);
    var scope 
    = engine.Runtime.Globals;
    var x 
    = new Data { X = 123 };
    scope.SetVariable(
    "x", x);
    code.Execute(scope);
    Console.WriteLine(x.X);

    读取Python上下文对象实例属性

    img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
    var py = @"
    class Class1:
      def __init__(self):
        self.i = 100
      def inc(self):
        self.i=self.i+100
    o = Class1()
    ";
    var o 
    = scope.GetVariable("o");
    var i 
    = engine.Operations.GetMember<int>(o, "i"); 

    读取Python上下文对象实例方法
    engine.Execute("o.inc()", scope); //已经在上下文环境中执行此对象方法

目录
相关文章
|
1月前
|
开发框架 JavaScript 前端开发
揭秘:如何让你的asp.net页面变身交互魔术师——先施展JavaScript咒语,再引发服务器端魔法!
【8月更文挑战第16天】在ASP.NET开发中,处理客户端与服务器交互时,常需先执行客户端验证再提交数据。传统上使用ASP.NET Button控件直接触发服务器事件,但难以插入客户端逻辑。本文对比此法与改进方案:利用HTML按钮及JavaScript手动控制表单提交。后者通过`onclick`事件调用JavaScript函数`SubmitForm()`来检查输入并决定是否提交,增强了灵活性和用户体验,同时确保了服务器端逻辑的执行。
35 5
|
20天前
|
数据库 C# 开发者
WPF开发者必读:揭秘ADO.NET与Entity Framework数据库交互秘籍,轻松实现企业级应用!
【8月更文挑战第31天】在现代软件开发中,WPF 与数据库的交互对于构建企业级应用至关重要。本文介绍了如何利用 ADO.NET 和 Entity Framework 在 WPF 应用中访问和操作数据库。ADO.NET 是 .NET Framework 中用于访问各类数据库(如 SQL Server、MySQL 等)的类库;Entity Framework 则是一种 ORM 框架,支持面向对象的数据操作。文章通过示例展示了如何在 WPF 应用中集成这两种技术,提高开发效率。
35 0
|
4月前
|
PHP Windows
php扩展com_dndnet(PHP与.NET框架进行交互)
php扩展com_dndnet(PHP与.NET框架进行交互)
php扩展com_dndnet(PHP与.NET框架进行交互)
|
4月前
|
JavaScript C#
【傻瓜级JS-DLL-WINCC-PLC交互】2.wincc使用C#开发的.net控件
【傻瓜级JS-DLL-WINCC-PLC交互】2.wincc使用C#开发的.net控件
88 0
|
4月前
|
JavaScript Linux C#
【傻瓜级JS-DLL-WINCC-PLC交互】1.C#用windows窗体控件创建.net控件
【傻瓜级JS-DLL-WINCC-PLC交互】1.C#用windows窗体控件创建.net控件
126 0
|
SQL JSON 前端开发
.NET+Ajax+ashx 实现Echarts图表动态交互
前言:   使用Echarts展示图表效果,在这里只做了四种案例:折线、柱状、圆形、雷达。当初是一位朋友用到Echarts展示数据,他没有太多时间弄,所以我就帮他搞出来,当初刚接触的时候也是一头雾水,不知道该怎么下手,网上类似的案例有也不多,并且不是自己想要的效果。
1787 0
|
XML JSON 前端开发
.net Ajax与后台一般处理程序(ashx) 交互
    本文主要实现无动态刷新查询后台数据功能,主要用到ajax+ashx+sqlserver进行交互. 首先需要引用Jquery: html脚本: 前台通过一个事件来调用ashx: $(function () { $("#tb_corpName").
1595 0
|
JavaScript C# Ruby
.NET DLR &ndash; IronPython- Silverlight 微软的战略性眼光
一、.NET Dynamic Language Runtime 随着.NET 4.0 即将正式发布,最令人激动的无疑是动态语言运行时(Dynamic Language Runtime—DLR)这个新特性,终于要开始大放光芒了。
933 0
|
13天前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
21 7