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

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

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

В приложении потребовались макросы. Мне подходит синтаксис C#, поэтому хочу использовать динамическую компиляцию. Вопрос по интеграции скомпилированного кода и взаимодействию его с остальным объектами в приложении. В примерах с динамической компиляцией обычно компилируют новый класс, затем создают экземпляр объекта этого класса и затем дергают у него методы. Я же хочу дополнить (добавить,переопределить...) скомпилированным кодом метод в имеющимся классе, чтобы из него можно было обращаться к приватным переменным и методам. Как лучше сделать что-то подобное?
Листинг программы
  1. using Microsoft.CSharp;
  2. using System.CodeDom.Compiler;
  3. using System.Reflection;
  4. ...
  5. class MacrosClass
  6. {
  7. private int Var1 = 3;
  8. private int Var2 = 5;
  9. // Код макроса примерно такой
  10. private string MacrosCode =
  11. @"
  12. int a = Method1();
  13. int b = Var1 + Var2 + a;
  14. Method2(b);
  15. ";
  16. public void MacrosCompileAndExecute()
  17. {
  18. // Настраиваем компилятор
  19. Dictionary<string, string> providerOptions = new Dictionary<string, string>
  20. {
  21. {"CompilerVersion", "v3.5"}
  22. };
  23. CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
  24. CompilerParameters compilerParams = new CompilerParameters
  25. {
  26. GenerateExecutable = false,
  27. GenerateInMemory = true
  28. };
  29. // Компиляция
  30. CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, MacrosCode);
  31. // Что делать дальше?
  32. }
  33. private int Method1()
  34. {
  35. ...
  36. }
  37. private void Method2(int var)
  38. {
  39. ...
  40. }
  41. }
Смотрел еще DynamicMethod. Примерно то, что нужно, но надо чтобы принимал код C#. MSIL для макросов слишком суров и никак не подходит.
Еще вопрос, из компилируемой динамически программы недоступны классы из основной. Namespaces указаны верно, проблема в references. Помогает такое:
Листинг программы
  1. CompilerParameters compilerParams = new CompilerParameters
  2. {
  3. ...
  4. ReferencedAssemblies = { "application.exe" }
  5. };
где application.exe - сама программа. Но это как-то совсем некрасиво. Как сделать правильно?

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

textual
Листинг программы
  1. public class Test
  2. {
  3.     public static int Run()
  4.     {
  5.         var Provider = new Microsoft.CSharp.CSharpCodeProvider();
  6.         var Param = new System.CodeDom.Compiler.CompilerParameters();
  7.  
  8.         var Code = @"
  9. using System;
  10.  
  11. public class Class1
  12. {
  13.    
  14.    public int Method()
  15.    {
  16.        return Test.MethodA(2) + 4 * Test.MethodB(2);
  17.    }
  18. }
  19. ";
  20.  
  21.         Param.CompilerOptions = "/optimize+";
  22.         Param.GenerateInMemory = true;
  23.         Param.ReferencedAssemblies.Add( System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0].Name );
  24.  
  25.  
  26.         var Result = Provider.CompileAssemblyFromSource( Param, new string[] { Code } );
  27.         if (Result.Errors.Count > 0)
  28.         {
  29.             MessageBox.Show( Result.Errors[0].ErrorText );
  30.             return -1;
  31.         }
  32.  
  33.         dynamic Class1 = Result.CompiledAssembly.CreateInstance( "Class1" );
  34.         return Class1.Method();
  35.     }
  36.  
  37.     public static int MethodA(int a)
  38.     {
  39.         return a * 2;
  40.     }
  41.  
  42.     public static int MethodB(int b)
  43.     {
  44.         return b * 3;
  45.     }
  46. }

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


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

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

7   голосов , оценка 4.286 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы