Динамическая компиляция и внедрение полученного кода в приложение - 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; } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д