1

我当前的项目是一个应用程序,它允许您使用 C# 编写代码,然后使用 CSharpCodeProvider 执行它。只要代码本身是一个完整的应用程序,此时它就可以正常工作,例如:

using System;

namespace RuntimeCode {
    public static class Program {
        public static void Main() {
            Console.WriteLine("Hello, world!");
        }
    }
}

然后应用程序使用CompileAssemblyFromSourcewith编译给定的代码GenerateInMemory = true,然后在编译的程序集中调用该Main方法。

我的问题是,如何让编译后的代码访问主应用程序中的对象?

4

3 回答 3

1

请注意,运行时生成的代码作为单独的进程执行。因此,您需要执行跨进程通信:在您的主应用程序、主机应用程序和新创建的应用程序之间。

实现跨进程或跨域交换的一个好方法是在您的主应用程序或默认应用程序域中托管一个特殊服务。生成的程序集将成为客户端。

我建议使用 WCF 和NetNamedPipeBinding。您只需要配置合约和端​​点。


另请注意,唯一的GenerateInMemory=true控制是将生成的程序集是否从磁盘加载到内存。就是这样。


如果您将脚本加载到默认的 AppDomain 中,那就更简单了。只需创建一个静态成员:

namespace MyNamespace
{
    public class Core
    {
        public static Core Instance { get; set; }
    }
}

并通过完整类型名称访问它:

MyNamespace.Core.Instance;
于 2012-12-12T05:32:06.140 回答
0

然后应用程序编译给定的代码 […],然后在编译的程序集中调用 Main 方法。

我认为这几乎回答了你的问题。您正在编译的代码没有理由必须具有无参数Main()方法。例如,如果您需要访问的方法在IHost接口中,那么您可以要求您的脚本有一个Main带有 type 参数的方法IHost。然后,您将调用它,传入IHost.

于 2012-12-14T21:27:03.840 回答
0

您注入的代码无法访问主应用程序中定义的类和对象。(要访问主应用程序中定义的类,您可以再次在注入代码中使用反射,但对象不可访问。)

但是您可以简单地将数据作为参数发送到注入的代码:

using System;

namespace RuntimeCode {
    public static class Program {
        public static void StartPoint(object obj) {
            Console.WriteLine("Hello, world!");
        }
    }
}

StartPoint然后通过发送obj包含所需数据的对象来调用方法。

您可以使用所需的任何类型的对象。但它应该被注入的代码识别。

于 2017-08-09T15:09:07.883 回答