人本善良

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

Dynamic Compilation and Loading of .NET Objects

 

 
This is another approach to dynamic compilation of objects and their usage via Interfaces.

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);

 

posted on   简简单单2018  阅读(155)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示