包含DLR ScriptRuntime

DLR是微软的一个开源项目.为.NET影城程序提供了动态脚本注入支持.DLR构建的功能包含两个方面,一个是共享的动态类型系统,一个是标准的承载模型.但是VS并没有继承相关的DLL,大家可以从Codeplex获得源码.这里不得不提及CLR,它是整个运行环境的基础,DLR也是运行在其上,这样是由显而易见的好处的,CLR的垃圾垃圾回收,JIT编译,安全模式,DLR也能享用这些底层架构功能,如果我们对垃圾回收进行优化,或者是提供某种功能,那么DLR相应的也能享用这种便利.DLR内部为了提高执行效率,会让自己先编译脚本,然后缓存.这有些类似JIT机制.避免重复加载,解析外部脚本.

在实际业务逻辑中,我们希望能够实时动态执行存储在文件中的代码或者完整一个业务逻辑功能,甚至我们可以动态选择脚本语言引擎,在应用程序域中动态生成脚本,并注入脚本,来达到控制业务逻辑的目的.

ScriptRuntime: 创建 DLR 运行环境,这是整个执行过程的起始点,它表示一个全局的执行状态(比如程序集引用等等)。每个应用程序域(AppDomain)中可以启动多个 ScriptRuntime。

ScriptScope: 构建一个执行上下文,其中保存了环境及全局变量。宿主(Host)可以通过创建不同的 ScriptScope 来提供多个数据隔离的执行上下文。

ScriptEngine: DLR 动态语言(比如 IronPython) 执行类,可于解析和执行动态语言代码。

ScriptSource: 操控动态语言代码的类型,我们可以编译(Compile)、读取(Read Code Lines)或运行(Execute)代码。

CompiledCode: 调用 ScriptSource.Compile() 将源代码编译成 CompiledCode,这样多次执行就无需重复编译,从而提高执行性能。

ObjectOperations: 提供了相关方法,允许我们在宿主(Host)中操作 DLR 对象成员(Member)。

现在我们来构建脚本引擎

应用程序执行脚本的方法有很多种:

1.通过ScriptRuntime.ExcuteFile获得ScriptScope

2.通过ScriptRuntime.UseFile获得ScriptScope

3.通过ScriptRuntime.CreateScope获得ScriptScope,再执行Script>execute或ScriptScope.IncludeFile

4.通过ScriptRuntime.GetEngine或ScriptRuntime.GetEngineByFileName获得ScriptEngine.调用ScriptEngine的CreateScriptSourceFromStrng或CreateScriptSourceFromFile或CreateScriptSourceFromStream创建ScriptSource,再执行ScriptSource.Execute

5.有了ScriptSource也不一定要Execute,可以先调用Compile,产生CompiledCode,最后调用CompiledCOde.Execute.

说了这么多,你肯定觉得每个例子,说个JB,说不定又觉得我在忽悠你,我是那样的人吗?

下面看看JB,不对,是案例:

第一步,安装:我是用的是VS2012,我从http://ironpython.codeplex.com/releases/view/12482下载的是IronPython-2.6.msi(不大,7M作用),直接安装就可以了.使用默认的安装路径就可以了,C:\Program Files(86)\IronPython 2.6(这是我的默认路径)

第二步:引入相应的dll

看到引用了吗?右键单击,选择添加引用,将C:\Program Files(86)\IronPython 2.6的IronPython.dll,Microsoft.Scripting.Core.dll,Microsoft.Scripting.dll三个dll引入进来.

第三步:应用

C:\Program Files\IronPython 2.6\Tutorial\Tutorial.htm是IronPython的应用指导,写的很仔细。ipy.exe是IronPython 的运行控制台,如果你想学习IronPython 的语法可以使用这个工具。IronPython 的语法这里就不详细介绍了,如果想进一步学习,可以下载IronPython in Action。

看代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

//下面这二个命名空间必须要引入

using Microsoft.Scripting.Hosting;

using IronPython.Hosting;

namespace ConsoleApplication20

{

class Program

{

static void Main(string[] args)

{

/*因为本人没学过Python,所以不会,但是我学过shell和JS,感觉语法差不多,大同小异*/

ScriptEngine engine = Python.CreateEngine();

ScriptScope scope = engine.CreateScope();

var strExpression = "1+2";

var sourceCode = engine.CreateScriptSourceFromString(strExpression);

var actual = sourceCode.Execute<int>();

Console.WriteLine(actual);

Console.ReadKey();

}

}

}

这段代码是用来计算1+2的结果.

ScriptEngine和ScriptScope是在.net中使用IronPython脚本的两个基础类,ScriptSource是运行IronPython的基础类,这里sourceCode就是一个ScriptSource.

有时我们希望给IronPython代码中传入一个变量值:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

//下面这二个命名空间必须要引入

using Microsoft.Scripting.Hosting;

using IronPython.Hosting;

namespace ConsoleApplication20

{

class Program

{

static void Main(string[] args)

{

ScriptEngine engine = Python.CreateEngine();

ScriptScope scope = engine.CreateScope();

var strExpression = "\"hello:\" + str ";

var sourceCode = engine.CreateScriptSourceFromString(strExpression);

scope.SetVariable("str","python");

var actual=sourceCode.Execute<string>(scope);

scope.RemoveVariable("str");

Console.WriteLine(actual);

Console.ReadKey();

}

}

}

C#调用IronPython函数

ScriptEngine engine = Python.CreateEngine();

ScriptScope scope = engine.CreateScope();

var strExpression = @"def MyFunction(n):return 2*n ";

var sourceCode = engine.CreateScriptSourceFromString(strExpression).Compile().Execute(scope);

var func = engine.GetVariable<Func<int, int>>(scope, "MyFunction");

Console.WriteLine(func(3));

Console.ReadKey();

这里需要注意def MyFunction(n):前面不能有空格,return 2*n必须有空格

IronPython调用C#函数

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

//下面这二个命名空间必须要引入

using Microsoft.Scripting.Hosting;

using IronPython.Hosting;

namespace ConsoleApplication20

{

class Program

{

static void Main(string[] args)

{

ScriptEngine engine = Python.CreateEngine();

ScriptScope scope = engine.CreateScope();

var strExpression = "CMethod('Python')";

var sourceCode = engine.CreateScriptSourceFromString(strExpression);

scope.SetVariable("CMethod", (Func<string, string>)TMethod);

var actual = sourceCode.Execute<string>(scope);

scope.RemoveVariable("CMethod");

Console.WriteLine(actual);

Console.ReadKey();

}

public static string TMethod(string info)

{

return "Hello:" + info;

}

}

}

案例:如果需要使用某个对象中的某个函数

using System;

using System.Collections.Generic;

using System.Linq;

using System.Reflection;

using System.Text;

using System.Threading.Tasks;

//下面这二个命名空间必须要引入

using Microsoft.Scripting.Hosting;

using IronPython.Hosting;

namespace ConsoleApplication20

{

class Program

{

static void Main(string[] args)

{

ScriptEngine engine = Python.CreateEngine();

ScriptScope scope = engine.CreateScope();

Test test = new Test();

var strExpression = @"test.Hello()

";

var sourceCode = engine.CreateScriptSourceFromString(strExpression);

scope.SetVariable("test", test);

var actual = sourceCode.Execute<string>(scope);

Console.WriteLine(actual);

Console.ReadKey();

}

}

public class Test

{

public void Hello()

{

Console.WriteLine("hello ,world");

}

}

}

案例:如果需要在IronPython实例化使用某个对象,就稍微复杂一点:

using IronPython.Hosting;

using Microsoft.Scripting.Hosting;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

namespace IronPythonTest

{

class Program

{

static void Main(string[] args)

{

ScriptEngine engine = Python.CreateEngine();

ScriptScope scope = engine.CreateScope();

var strExpression = @"

import clr, sys

clr.AddReference('IronPythonTest')

from IronPythonTest import *

test=Test()

test.Hello()

";

var sourceCode = engine.CreateScriptSourceFromString(strExpression);

var actual = sourceCode.Execute<string>(scope);

Console.WriteLine(actual);

Console.ReadKey();

}

}

public class Test

{

public string Hello()

{

return "Hello World";

}

}

}

C#编程(七十一)----------DLR ScriptRuntime的更多相关文章

  1. 孤荷凌寒自学python第七十一天开始写Python的第一个爬虫

    孤荷凌寒自学python第七十一天开始写Python的第一个爬虫 (完整学习过程屏幕记录视频地址在文末) 在了解了requests模块和BeautifulSoup模块后,今天开始真正写一个自己的爬虫代 ...

  2. 第三百七十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现我的搜索以及热门搜索

    第三百七十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现我的搜索以及热门 我的搜素简单实现原理我们可以用js来实现,首先用js获取到 ...

  3. 深度学习(七十一)darknet 源码阅读

    深度学习(七十一)darknet 源码阅读

  4. “全栈2019”Java第七十一章:外部类访问静态内部类成员详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  5. 《手把手教你》系列技巧篇(七十一)-java+ selenium自动化测试-自定义类解决元素同步问题(详解教程)

    1.简介 前面宏哥介绍了几种关于时间等待的方法,也提到了,在实际自动化测试脚本开发过程,百分之90的报错是和元素因为时间不同步而发生报错.本文介绍如何新建一个自定义的类库来解决这个元素同步问题.这样, ...

  6. C#编程(七十一)---------- 自定义特性

    自定义特性 在说自定义之前,有必要先介绍一些基本的概念. 元数据:就是C#中封装的一些类,无法修改,类成员的特性被称为元数据中的注释 1.什么是特性? (1)属性和特性的区别 属性:属性是面向对象思想 ...

  7. 学习ASP.NET Core Razor 编程系列十一——把新字段更新到数据库

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  8. Linux 网络编程七(非阻塞socket:epoll--select)

    阻塞socket --阻塞调用是指调用结果返回之前,当前线程会被挂起.函数只有在得到结果之后才会返回. --对于文件操作 read,fread函数调用会将线程阻塞(平常使用read感觉不出来阻塞, 因 ...

  9. TCP编程(七)

    此为网络编程的一个系列,后续会把内容补上...

随机推荐

  1. Django Rest Framework-APIView源码分析

    class APIView(View): # The following policies may be set at either globally, or per-view. renderer_c ...

  2. MySQL Replication Report

    很多人都会MySQL主从框架的搭建,但很多人没有真正理解同步基本用途.同步的基本原理,还有当Master和Slave同步断开后的处理以及导致Master和slave不同步的原因等等,当你对这些都了如指 ...

  3. windows下安装apache zookeeper

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提供的功 ...

  4. 欢迎来到abc2237512422的博客

    这是第一篇博文. 本博客已迁移到 abc233.site

  5. Educational Codeforces Round 41 (Rated for Div. 2)

    这场没打又亏疯了!!! A - Tetris : 类似俄罗斯方块,模拟一下就好啦. #include<bits/stdc++.h> #define fi first #define se ...

  6. 【noip模拟赛2】牛跳

    描述 John的奶牛们计划要跳到月亮上去.它们请魔法师配制了P(1 <= P <=150,000)种药水,这些药水必需安原来的先后次序使用,但中间可以跳过一些药水不吃.每种药水有一个“强度 ...

  7. 028 Partitioner:数据分区器

    Partitioner:数据分区器,决定数据到下一个RDD的时候在那一个分区 HashPartitioner:根据key的hashCode值来实现 RangePartitioner: 根据key所属范 ...

  8. MySQL数据库之存储过程与存储函数

    1 引言 存储过程和存储函数类似于面向对象程序设计语言中的方法,可以简化代码,提高代码的重用性.本文主要介绍如何创建存储过程和存储函数,以及存储过程与函数的使用.修改.删除等操作. 2 存储过程与存储 ...

  9. odoo 工作流

    odoo工作流 介绍 新版本的odoo开始减少workflow的使用,推荐使用workflow-ish的方式来处理工作流过程 很多模块中还是使用到工作流,这里我记录一个简单的实例,欢迎大家给出建议. ...

  10. 详解django三种文件下载方式

    推荐使用FileResponse,从源码中可以看出FileResponse是StreamingHttpResponse的子类,内部使用迭代器进行数据流传输. 在实际的项目中很多时候需要用到下载功能,如 ...