Динамическая компиляция и внедрение полученного кода в приложение - C#

Узнай цену своей работы

Формулировка задачи:

В приложении потребовались макросы. Мне подходит синтаксис C#, поэтому хочу использовать динамическую компиляцию. Вопрос по интеграции скомпилированного кода и взаимодействию его с остальным объектами в приложении. В примерах с динамической компиляцией обычно компилируют новый класс, затем создают экземпляр объекта этого класса и затем дергают у него методы. Я же хочу дополнить (добавить,переопределить...) скомпилированным кодом метод в имеющимся классе, чтобы из него можно было обращаться к приватным переменным и методам. Как лучше сделать что-то подобное?
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
...
    class MacrosClass
    {
        private int Var1 = 3;
        private int Var2 = 5;
 
        // Код  макроса примерно такой
        private string MacrosCode =
        @"
        int a = Method1();
        int b = Var1 + Var2 + a;
        Method2(b);
        ";
 
        public void MacrosCompileAndExecute()
        {
            // Настраиваем компилятор            
            Dictionary<string, string> providerOptions = new Dictionary<string, string>
            {
                {"CompilerVersion", "v3.5"}
            };
 
            CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
 
            CompilerParameters compilerParams = new CompilerParameters
            {
                GenerateExecutable = false,
                GenerateInMemory = true
            };
 
            // Компиляция
            CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, MacrosCode);
            // Что делать дальше?
        }
 
        private int Method1()
        {
            ...
        }
 
        private void Method2(int var)
        {
            ...
        }
    }
Смотрел еще DynamicMethod. Примерно то, что нужно, но надо чтобы принимал код C#. MSIL для макросов слишком суров и никак не подходит.
Еще вопрос, из компилируемой динамически программы недоступны классы из основной. Namespaces указаны верно, проблема в references. Помогает такое:
CompilerParameters compilerParams = new CompilerParameters
{
    ...
    ReferencedAssemblies = { "application.exe" }
};
где application.exe - сама программа. Но это как-то совсем некрасиво. Как сделать правильно?

Решение задачи: «Динамическая компиляция и внедрение полученного кода в приложение»

textual
Листинг программы
public class Test
{
    public static int Run()
    {
        var Provider = new Microsoft.CSharp.CSharpCodeProvider();
        var Param = new System.CodeDom.Compiler.CompilerParameters();
 
        var Code = @"
using System;
 
public class Class1
{
    
    public int Method()
    {
        return Test.MethodA(2) + 4 * Test.MethodB(2);
    }
}
";
 
        Param.CompilerOptions = "/optimize+";
        Param.GenerateInMemory = true;
        Param.ReferencedAssemblies.Add( System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].Name );
 
 
        var Result = Provider.CompileAssemblyFromSource( Param, new string[] { Code } );
        if (Result.Errors.Count > 0)
        {
            MessageBox.Show( Result.Errors[0].ErrorText );
            return -1;
        }
 
        dynamic Class1 = Result.CompiledAssembly.CreateInstance( "Class1" );
        return Class1.Method();
    }
 
    public static int MethodA(int a)
    {
        return a * 2;
    }
 
    public static int MethodB(int b)
    {
        return b * 3;
    }
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.286 из 5
Похожие ответы