通过Roslyn动态生成程序集
之前写过篇文章如何通过Roslyn构建自己的C#脚本,今天本来打算测试一下这部分API在新的版本中的变化,结果发现它的脚本引擎找不到了,翻了一下官方文档,貌似说暂时性的移除了。便看了一下它动态生成程序集的API,这里简单的介绍一下使用方法。
首先需要在NUGET中添加CodeAnalysis的引用(目前还是预览版,注意在NuGet中开启预览版的选择)

动态生成程序集主要有如下几步
- 将代码解析成语法树
- 将语法树进行编译
- 通过Emit生成程序集
然后就是如何使用了
- 动态加载程序集
- 通过反射调用方法
代码如下:
static void CompileAndRun()
{
var text = @"
public class Calculator
{
public static int Evaluate() { return 3 + 2 * 5; }
}";
var tree = SyntaxFactory.ParseSyntaxTree(text);
var compilation = CSharpCompilation.Create("calc.dll", new[] { tree },
options: new
CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
references: new[] { new
MetadataFileReference(typeof(object).Assembly.Location) });
Assembly compiledAssembly;
using (var stream = new
MemoryStream())
{
var compileResult = compilation.Emit(stream);
compiledAssembly = Assembly.Load(stream.GetBuffer());
}
var calculatorClass = compiledAssembly.GetType("Calculator");
var evaluateMethod = calculatorClass.GetMethod("Evaluate");
var result = evaluateMethod.Invoke(null, null).ToString();
Console.WriteLine(result);
}
另外,若只是实现本例所示的功能的话,.Net 1.0中就存在的CodeDom就能实现,上面的步骤和CodeDom的也是非常类似的。CodeDom实际上是Roslyn的前身,Roslyn能提供更多高级的功能,关于它们之间的区别和联系,StackWverFlow上的一篇帖子Microsoft Roslyn vs. CodeDom里介绍得比较详细,这里我就不多介绍了。
通过Roslyn动态生成程序集的更多相关文章
- Roslyn 编译器Api妙用:动态生成类并实现接口
在上一篇文章中有讲到使用反射手写IL代码动态生成类并实现接口. 反射的妙用:C#通过反射动态生成类型继承接口并实现 有位网友推荐使用 Roslyn 去脚本化动态生成,今天这篇文章就主要讲怎么使用 Ro ...
- C#动态创建和动态使用程序集、类、方法、字段等
C#动态创建和动态使用程序集.类.方法.字段等 分类:技术交流 (3204) (3) 首先需要知道动态创建这些类型是使用的一些什么技术呢?其实只要相关动态加载程序集呀,类呀,都是使用反射,那么动 ...
- Emit动态生成代码
Emit动态生成代码 引用:秒懂C#通过Emit动态生成代码 首先需要声明一个程序集名称, // specify a new assembly name var assemblyName = new ...
- DevExpress 中根据数据库字典动态生成卡式菜单 z
第三方的Devexpress套件因为要使用权限机制控制不同用户进入系统显示菜单所以要配合字典数据动态生成.在WEB中这种问题灰常的轻松在winform里就稍微有点不同为了用DEV实现卡式菜单有组的概念 ...
- 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习)
原文 利用Mono.Cecil动态修改程序集来破解商业组件(仅用于研究学习) Mono.Cecil是一个强大的MSIL的注入工具,利用它可以实现动态创建程序集,也可以实现拦截器横向切入动态方法,甚至还 ...
- 秒懂C#通过Emit动态生成代码
首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new AssemblyName("Kitty&qu ...
- 秒懂C#通过Emit动态生成代码 C#使用Emit构造拦截器动态代理类
秒懂C#通过Emit动态生成代码 首先需要声明一个程序集名称, 1 // specify a new assembly name 2 var assemblyName = new Assembly ...
- Emit动态生成代理类用于监控对象的字段修改
利用Emit动态生成代理对象监控对象哪些字段被修改,被修改为什么值 被Register的对象要监控的值必须是Virtual虚类型 必须使用CreateInstance创建对象 必须使用DynamicP ...
- 反射的妙用:C#通过反射动态生成类型继承接口并实现
起因 最近想自己鼓捣个RPC,想着简化RPC调用方式,直接申明接口,然后根据接口的属性去配置RPC调用的相关信息.有一种说法叫申明式调用. 简单来说就是,申明一个interface,动态继承并实例化, ...
随机推荐
- java字符串 64位编码
byte[] encodeBase64 = Base64.encodeBase64("到了是是是是".getBytes("UTF-8")); System.ou ...
- codeforce C. Okabe and Boxes
题目传送门 这道题 每次删除一个点 那么这个点必然在栈里面 那么如果堆顶不是他 我们就需要一次操作使得堆合理 这时我们可以把他删除然后把他下面的点打个标记表示这下面的点以后想怎么排就怎么排以后都不需要 ...
- 【洛谷 P4886】 快递员 (点分治)
这题因为一些小细节还是\(debug\)了很久...不过我第一次用脚本对拍,不亏. 先随便找一个点作为根,算出答案,即所有点对到这个点的距离和的最大值,并记录所有距离最大的点对.如果这个点在任意一个距 ...
- bzoj 2245 费用流
比较裸 源点连人,每个人连自己的工作,工作连汇,然后因为人的费用是 分度的,且是随工作数非降的,所以我们拆边,源点连到每个人s+1条边 容量是每段的件数,费用是愤怒 /**************** ...
- ssh保持连接
转载自: http://www.neatstudio.com/show-625-1.shtml http://www.linuxidc.com/Linux/2010-05/26031.htm (这一篇 ...
- Java坦克大战 (三) 之可完全控制坦克朝八个方向运动
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- Tk写的发邮件小程序
from tkinter import * import smtplib from email.mime.text import MIMEText from email.header import H ...
- Iphone安装Pinterest
由于Pinterest在中国的app store下架了,也就搜索不到该应用.所以只能上美国的app store下载. 1,下载itunes,登录vpn,注册新的apple id: 2,手机连接vpn, ...
- 官方文档,才是正途-docker-compose
需要的ingress网络映射,还是host宿主机端口映射: https://docs.docker.com/compose/compose-file/#secrets ================ ...
- std::string 字符串大小写转换(转)
该问题归结为std::transform函数的使用 函数原型 template < class InputIterator, class OutputIterator, class UnaryO ...