Dynamic Compilation and Loading of .NET Objects
Introduction
When I read about dynamic compilation in .NET (which is a great feature) for the first time, I soon got stuck with the samples I found. Mostly, they covered the idea of writing small functions dynamically as we can find on various web pages with tutorials. These samples discuss problems like speed of execution or different ways to access the compiled function. But I wanted more. My idea was: I want to compile and use an whole object (or even some more) with members and methods without taking too much care about reflection (yes, some reflection is necessary, I know).
Using the Code
Basically, our best friends here are Microsoft.CSharp
and System.CodeDom.Compiler
. But to make this simple magic of having an instance of the dynamically compiled object, we also use a simple interface like this:
using System;
namespace Iface {
public interface ImyInterface
{
string text {get; set;}
int number {get; set;}
int Func (int a, int b);
}
}
To make this interface available to the dynamically compiled code, I put this interface into a calls library, called "Iface.dll".
For the basic program, I add a reference to the Iface.dll and add the namespace together with all others necessary for this example:
using System;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;
using Iface;
The code for the dynamically compiled object is as follows:
const string code=@"
using System;
namespace TestClass
{
public class MyClass : Iface.ImyInterface
{
public int i;
public string text {get; set;}
public int number {get; set;}
public int Func (int a, int b){
i=a+b;
return a+b;
}
}
}
";
As you can see, it's just an implementation of the interface doing nothing special.
For the compilation at runtime, we need a CSharpCodeProvider
and CompilerParameters
:
CSharpCodeProvider provider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.ReferencedAssemblies.Add("Iface.dll");
parameters.GenerateInMemory = true;
Please note: When the program is compiled, a copy of the "Iface.dll" is placed in the same directory as the executable. So, the path for the referenced assembly is limited to "Iface.dll".
Next step: Compilation and some error handling.
CompilerResults results = provider.CompileAssemblyFromSource(parameters, code); if (results.Errors.HasErrors)
{
StringBuilder sb = new StringBuilder();
foreach (CompilerError error in results.Errors)
{
sb.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
}
throw new InvalidOperationException(sb.ToString());
}
And finally we get our object:
Assembly assembly = results.CompiledAssembly;
Type asmType = assembly.GetType("TestClass.MyClass");
Type[] argTypes=new Type[] { };
ConstructorInfo cInfo=asmType.GetConstructor(argTypes);
ImyInterface myclass=(ImyInterface)cInfo.Invoke(null); int result=myclass.Func(1,2);
Console.WriteLine("and the result is: {0}",result);
Console.ReadKey(true);
Dynamic Compilation and Loading of .NET Objects的更多相关文章
- Delphi DLL制作和加载 Static, Dynamic, Delayed 以及 Shared-Memory Manager
一 Dll的制作一般分为以下几步:1 在一个DLL工程里写一个过程或函数2 写一个Exports关键字,在其下写过程的名称.不用写参数和调用后缀.二 参数传递1 参数类型最好与window C++的参 ...
- ora-00600笔记
一. ORA-600 概述 Errorsof the form ORA-600 are called internal errors. This section clarifies themisund ...
- Unity 5 Game Optimization (Chris Dickinson 著)
1. Detecting Performance Issues 2. Scripting Strategies 3. The Benefits of Batching 4. Kickstart You ...
- IronPython Architecture
[IronPython] IronPython is an implementation of the Python programming language written by the CLR t ...
- oracle-Expdp/impdp命令
建立逻辑路径 create or replace directory dumpdir as 'c:\'; grant read,write on directory dumpdir to scott; ...
- Orchard源码分析(5.1):Host初始化(DefaultOrchardHost.Initialize方法)
概述 Orchard作为一个可扩展的CMS系统,是由一系列的模块(Modules)或主题(Themes)组成,这些模块或主题统称为扩展(Extensions).在初始化或运行时需要对扩展进行安装:De ...
- [你必须知道的.NET]第三十一回,深入.NET 4.0之,从“新”展望
发布日期:2009.05.22 作者:Anytao © 2009 Anytao.com ,Anytao原创作品,转贴请注明作者和出处. /// <summary> /// 本文开始,将以& ...
- SCI&EI 英文PAPER投稿经验【转】
英文投稿的一点经验[转载] From: http://chl033.woku.com/article/2893317.html 1. 首先一定要注意杂志的发表范围, 超出范围的千万别投,要不就是浪费时 ...
- 【转载】Android Studio 设置内存大小及原理
http://www.cnblogs.com/justinzhang/p/4274985.html http://tsroad.lofter.com/post/376316_69363ae Andro ...
随机推荐
- 微信小程序_(组件)组件基础
(progress.text.block) 组件基础效果 官方文档:传送门 Page({ /** * 页面的初始数据 */ data: { text:"Gary 微信小程序\n", ...
- 事件总线(EventBus)
Vue.prototype.$EventBus = new Vue() 不建议用,尽量用vuex,eventbus过于消耗浏览器资源 傻瓜版状态管理 一般的状态传递是在同时显示的情况下,倘若是在不同时 ...
- 消息队列rabbitmq/kafka
12.1 rabbitMQ 1. 你了解的消息队列 rabbitmq是一个消息代理,它接收和转发消息,可以理解为是生活的邮局.你可以将邮件放在邮箱里,你可以确定有邮递员会发送邮件给收件人.概括:rab ...
- opencv_将图像上的4个点按逆时针排序
1:代码如下: #include "stdafx.h" #include "cxcore.h" #include "cvcam.h" #in ...
- [翻译]C#中异步方法的性能特点
翻译自一篇博文,原文:The performance characteristics of async methods in C# 异步系列 剖析C#中的异步方法 扩展C#中的异步方法 C#中异步方法 ...
- 190707Python-Redis
一.Redis的简单使用 Redis操作模式 # Author:Li Dongfei import redis r = redis.Redis(host='192.168.56.7', port=63 ...
- Golang协程实现流量统计系统(3)
进程.线程.协程 - 进程:太重 - 线程:上下文切换开销太大 - 协程:轻量级的线程,简洁的并发模式 Golang协程:goroutine Hello world package main impo ...
- tensorflow实现LeNet-5模型
网络结构如下: INPUT: [28x28x1] weights: 0 CONV5-32: [28x28x32] weights: (5*5*1+1)*32 POOL2: [14x14x32] wei ...
- [常用的SQL语句总结]
1. 创建数据库DataBase create database 数据库名称; 2. 删除数据库DataBase drop database 数据库名称 drop database 数据库名称1, ...
- NSIS打包electron程序为exe安装包
在我的上一篇博客已经介绍了将electron程序生成一个exe可执行文件,但是这并不是最终能够发给用户用来安装的最终安装包,下面我们就介绍如何使用NISI将我们的应用程序打包成安装包: 上一篇博客我们 ...