对于非常特殊情况,我希望能够在配置条目中存储C#代码,并在运行时使用此代码填充空函数。例如,假设在初始运行时我开始使用如下方法:
bool Evaluate(int number)
{
return false;
}
我有一个如下所示的配置条目:
<add key="EvaluateCode" value="if (number > 5) { return true; } else { return false; }"/>
加载 EvaluateCode 配置条目后,我想替换 Evaluate 的函数体,使它看起来像这样:
bool Evaluate(int number)
{
if (number > 5) { return true; } else { return false; }
}
完成“替换”之后, Evaluate 函数应该按照代码的规定运行,就像代码没有动态加载一样。
我怎样才能在C#中实现这个目标?
加分:实施此功能会有什么风险?我该如何减轻这些风险?
答案 0 :(得分:2)
基本上你要求能够在运行时编译c#代码,这是可能的,并且描述为here
答案 1 :(得分: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
作为输出。基本上,在“注入”之前(它不是真正的注入......它更像是一个fascade),该方法返回false。在“注入”之后,它返回true(如预期的那样)。