Динамическая компиляция и внедрение полученного кода в приложение - C#
Формулировка задачи:
В приложении потребовались макросы. Мне подходит синтаксис C#, поэтому хочу использовать динамическую компиляцию. Вопрос по интеграции скомпилированного кода и взаимодействию его с остальным объектами в приложении. В примерах с динамической компиляцией обычно компилируют новый класс, затем создают экземпляр объекта этого класса и затем дергают у него методы.
Я же хочу дополнить (добавить,переопределить...) скомпилированным кодом метод в имеющимся классе, чтобы из него можно было обращаться к приватным переменным и методам. Как лучше сделать что-то подобное?
где application.exe - сама программа. Но это как-то совсем некрасиво. Как сделать правильно?
Листинг программы
- 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" }
- };
Решение задачи: «Динамическая компиляция и внедрение полученного кода в приложение»
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;
- }
- }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д