2013-12-06 2 views
0

Для очень особых обстоятельств, я хотел бы иметь возможность хранить код C# в записи конфигурации и заполнять пустую функцию с помощью этого кода во время выполнения. Например, предположим, что на первом прогоне я начинаю с такими методами, как это:Загрузка тела метода из строки?

bool Evaluate(int number) 
{ 
    return false; 
} 

У меня есть запись конфигурации, которая выглядит следующим образом:

<add key="EvaluateCode" value="if (number > 5) { return true; } else { return false; }"/> 

После загрузки записи конфигурации EvaluateCode Я хотел бы заменить функцию тела Оценка так, что это выглядит следующим образом:

bool Evaluate(int number) 
{ 
    if (number > 5) { return true; } else { return false; } 
} 

После этой «замены» функция Evaluate должна вести себя так, как диктует код, так же, как если бы код не был загружен динамически.

Как я мог добиться этого в C#?

Бонус: Каковы были бы риски реализации такой функции? Как я могу смягчить эти риски?

ответ

1

Это звучало как весело .. так что я решил попробовать.

Нет необходимости upvote .. просто выскакивают это здесь, так что я могу сослаться на него в будущем :)

Учитывая ниже класс:

class DynamicMethodTest { 
    private MethodInfo _methodToCall; 
    private object _obj; 

    public void PerformInjection(string newBody) { 
     using (var codeProvider = 
     new Microsoft.CSharp.CSharpCodeProvider()) { 
      var res = codeProvider.CompileAssemblyFromSource(
       new System.CodeDom.Compiler.CompilerParameters() { 
        GenerateInMemory = true 
       }, 
       "public class StubClass { public bool Evaluate(int number) { " + newBody + " }}" 
      ); 

      var type = res.CompiledAssembly.GetType("StubClass"); 

      _obj = Activator.CreateInstance(type); 

      _methodToCall = _obj.GetType().GetMethod("Evaluate"); 
     } 
    } 

    public bool Evaluate(int number) { 
     if (_methodToCall != null) 
      return (bool)_methodToCall.Invoke(_obj, new object[] { number }); 

     return false; 
    } 
} 

Мы можем сделать это:

public class Program { 
    public static void Main() { 
     var dynamicTest = new DynamicMethodTest(); 

     Console.WriteLine(dynamicTest.Evaluate(15)); // False 

     dynamicTest.PerformInjection("if (number > 5) { return true; } else { return false; }"); 

     Console.WriteLine(dynamicTest.Evaluate(15)); // True 

     Console.Read(); 
    } 

} 

Это результат:

False 
True 

Как выход. В принципе, перед «Инъекцией» (ее не очень-то инъекцией), ее более увлекательной) метод возвращает false. После «Injection» он возвращает true (как и ожидалось).

+0

Симон. Это именно то, что я искал! Это прямой ответ на мой вопрос, который очень помог мне в том, что я пытаюсь сделать. Спасибо. – Dalal

2

По существу вы просите возможность компилировать C# код во время выполнения, что возможно, и описывается here

+0

Я удивлен, что раньше этого не встречал. Спасибо, что указали на меня. – Dalal

Смежные вопросы