在运行时编译并使用类
问题描述:
我正在开发一种规则引擎,用户将规则定义为一组条件和操作。这些条件和行为然后被解析成要执行的代码。我能够生成没有任何问题的代码。我被困在编译它然后加载类的地步。在运行时编译并使用类
如何获取一串动态生成的源代码并在运行时进行编译?
我该如何执行该代码?
我想能够拥有一个静态的规则列表,这些规则会随着规则的添加而更新。喜欢的东西:
static Dictionary<string, Rule> Rules { get; set; }
static void RefreshRules()
{
var newRules = DataLayer.GetRules().Where(r => !this.Rules.ContainsKey(r.Name));
foreach (var rule in newRules)
{
this.Rules[rule.Name] = CompileRule(rule.Code);
}
}
或者我会重新编译的程序集,然后重新放回我已经在运行的应用程序?
答
我,你会推荐他们时变得相当可读使用Expression Trees而不是动态编译代码。
当您编译某些源代码时,生成的程序集会粘贴到主应用程序中,并且无法再分离。这导致了越来越多的内存使用,并导致潜在的危险行为。表达式树已经被创建,只用于像你的目标。
答
有些粗糙例如(编译源代码,创建实例,调用与使用反射PARAMS法):
CodeDomProvider P = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("C#");
CompilerParameters O = new CompilerParameters();
O.GenerateInMemory = true;
O.ReferencedAssemblies.Add(@"System.dll");
//O.ReferencedAssemblies.Add(@"System.Net.dll");
O.IncludeDebugInformation = false;
CompilerResults R = P.CompileAssemblyFromSource(O, new string[] { "using System; using System.Reflection; namespace ABC.TestXXX { // your source code goes here }" });
Assembly _B_ = R.CompiledAssembly;
// create an instance
object YY = _B_.CreateInstance("ABC.TestXXX.MyClass");
// call method returning bool and taking one string and one object
YR = (bool)_B_.GetType("ABC.TestXXX.MyClass").GetMethod("TestB").Invoke(YY, new object[] { "Hallo", SomeObject });
与细节的某些链接:
- http://msdn.microsoft.com/en-us/library/system.codedom.compiler.codedomprovider%28v=VS.100%29.aspx
- http://msdn.microsoft.com/en-us/library/system.codedom.compiler.compilerparameters.aspx
对于你的情况,你可以制定规则的行动<> /代表这反过来又调用编译方法,把那些进入词典<> ...所以它调用等
从这里开始:http://msdn.microsoft.com/en-us/library/650ax5cx.aspx;我过去使用过CodeDom,但没有代码示例方便正确的答案。 –
检出http://*.com/questions/5766373/how-does-linqpad-compile-code –
是否有你不想使用规则引擎的原因,比如Drools? – Amy