如何将外部动态编译的代码强制转换为内部接口,以便可以在托管代码中引用它?

时间:2019-07-08 14:14:44

标签: c# csharpcodeprovider dynamic-compilation

我有以下几行代码:

// CONTENTS OF code.txt

namespace ExternalCode
{
    public class MyClass : ICompiledExternalCode
    {
        public string TestMethod(string input) {
            return input + "" OK!"";
        }
    }

    public interface ICompiledExternalCode
    {
        string TestMethod(string input);
    }
}

我在运行时使用以下代码加载并编译它:

var src = GetExternalCode();
var csc = new CSharpCodeProvider();
var icc = csc.CreateCompiler();
var params = CompilerParameters
{
    GenerateExecutable = false,
    GenerateInMemory = true
};

var results = icc.CompileAssemblyFromSource(params, src);
if (results.Errors.Count > 0) throw new Exception("Errors during dynamic compile.");

object inst = results.CompiledAssembly.CreateInstance("ExternalCode.MyClass");
var method = inst.GetType().GetMethod("TestMethod");
method.Invoke(inst, new object[]{"Test"});

有效。以前,我只是直接声明dynamic inst而不是直接声明对象和调用方法,但是我发现这种解决方案比以方法名称作为魔术字符串来调用方法更加混乱。无论如何,我正在努力实现这样的目标:

object inst = results.CompiledAssembly.CreateInstance("ExternalCode.MyClass");
var castInst = (ICompiledExternalCode)castInst;
castInst.TestMethod("Test");

我已经在静态代码(包括适当的名称空间)中添加了ICompiledExternalCode接口的定义,但是关于将对象强制转换为错误的类型却引发了错误。

我唯一想到的是将接口声明推送到将由我的静态代码和动态代码加载的外部DLL。我真的想避免使用这种解决方案,因为我正在处理的项目已经充满了项目,外部程序集,我宁愿将它们放在一个地方。

有什么方法可以实现我的目标?

0 个答案:

没有答案