У меня есть следующие строки кода:
// 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, которая будет загружена как моим статическим, так и динамическим кодом. Я действительно хочу избежать этого решения, так как проект, над которым я работаю, уже наполнен проектами, внешними сборками, и я предпочел бы хранить вещи в одном месте.
Есть ли способ достичь того, к чему я стремлюсь?