Q:

C# динамическое компилирование

Всем привет.
У меня есть код, который компилирует на run time маленький кусочек другого кода
eq = "namespace test { 
    public class Test {
      public string Upper(string lower, string lower2) { 
         return lower.ToUpper() + lower2.ToUpper(); } } }";    

Но когда я его немного усложняю, 
eq = "namespace test { 
   public class Test{
     public int Itest(int str){
        MathFun mf = new MathFun();
        int result = mf.calcul(str);
        return result;}}}"; 

компилятор выдает ошибку.
Могу добавить, что класс MathFun в том же project где и main(), а его namespace — test.
Подскажите, как я могу компилировать мою «программку», где создаётся объект.

A:

Если для компиляции используется CodeDom (CSharpCodeProvider), то необходимо добавить в параметры компилятора ссылку на сборку, где находится тип MathFun. Путь к ней можно получить через typeof(MathFun).Assembly.Location:
namespace test
{
    // класс, к которому нужно получить доступ в генерируемой сборке
    public class MathFun
    {
        // в качестве примера метод просто возвращает свой аргумент
        public int calcul(int str)
        {
            return str;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var eq = @"namespace test { 
   public class Test{
     public int Itest(int str){
        MathFun mf = new MathFun();
        int result = mf.calcul(str);
        return result;}}}";

            var prms = new CompilerParameters();
            prms.GenerateInMemory = true;
            prms.GenerateExecutable = false;

            // добавляем референс на сборку с типом MathFun
            prms.ReferencedAssemblies.Add(typeof(MathFun).Assembly.Location);

            var provider = new CSharpCodeProvider();
            var compileResult = provider.CompileAssemblyFromSource(prms, eq);

            // тест созданной сборки, создание экземпляра класса Test и вызов метода Itest
            var typeTest = compileResult.CompiledAssembly.GetType("test.Test");
            var itestMethod = typeTest.GetMethod("Itest");
            var instance = Activator.CreateInstance(typeTest);

            var result = itestMethod.Invoke(instance, new object[] { 42 });
            Console.WriteLine(result); // выводит 42
        }
    }
}

Если же используется Roslyn, то аналогичную ссылку нужно добавить в массив объектов MetadataReference:
var syntaxTree = CSharpSyntaxTree.ParseText(eq);
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var refs = new[] {
    MetadataReference.CreateFromFile(typeof(MathFun).Assembly.Location),
    MetadataReference.CreateFromFile(typeof(object).Assembly.Location)
};

var compiler = CSharpCompilation.Create(
        "testasm", new[] { syntaxTree }, refs, options);

Assembly asm;
using (var stream = new MemoryStream()) {
    compiler.Emit(stream);
    stream.Seek(0, SeekOrigin.Begin);
    asm = Assembly.Load(stream.ToArray());
}

var typeTest = asm.GetType("test.Test");

// ...

Ошибки компиляции можно вывести в консоль:
// ...
var compileResult = provider.CompileAssemblyFromSource(prms, eq);

if (compileResult.Errors.HasErrors) {
    foreach (var error in compileResult.Errors) {
        Console.WriteLine(error);
    }
}

В вашем случае нужно проверить две вещи:

В компилируемом коде добавлены строки
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

Добавлены ссылки на WebDriver.dll и System.dll.

Вот такой код работает:
var eq =
@"using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace test {
    class Test {
        public void m()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl(""http://www.google.com"");
            IWebElement element = driver.FindElement(By.Name(""q""));
            element.SendKeys(""executeautomation"");
        }
    }
}";

var prms = new CompilerParameters();
prms.GenerateInMemory = true;
prms.GenerateExecutable = false;

// ссылка на WebDriver.dll (либо строкой прописать полный путь до этой сборки)
prms.ReferencedAssemblies.Add(typeof(OpenQA.Selenium.IWebDriver).Assembly.Location);
// ссылка на System.dll
prms.ReferencedAssemblies.Add("System.dll");

var provider = new CSharpCodeProvider();
var compileResult = provider.CompileAssemblyFromSource(prms, eq);

