【发布时间】:2015-06-16 16:14:16
【问题描述】:
我正在使用 Roslyn 尝试在运行时编译和运行代码。我已经对我在网上找到的一些代码进行了 ysed,并且它有些工作。
public Type EvalTableScript(string Script, CRMMobileFramework.EnbuUtils EnbuUtils, CRMMobileFramework.Includes.DBAdapter dbConn)
{
var syntaxTree = SyntaxTree.ParseText(Script);
var compilation = Compilation.Create("EnbuScript.dll",
options: new CompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary),
references: new[]
{
new MetadataFileReference(typeof(object).Assembly.Location),
new MetadataFileReference(typeof(EnbuUtils).Assembly.Location),
new MetadataFileReference(typeof(DBAdapter).Assembly.Location),
MetadataFileReference.CreateAssemblyReference("System.Data"),
MetadataFileReference.CreateAssemblyReference("System.Linq"),
MetadataFileReference.CreateAssemblyReference("System"),
MetadataFileReference.CreateAssemblyReference("System.XML")
},
syntaxTrees: new[] { syntaxTree });
var diagnostics = compilation.GetDiagnostics();
foreach (var diagnostic in diagnostics)
{
Console.WriteLine("Error: {0}", diagnostic.Info.GetMessage());
}
Assembly assembly;
using (var stream = new MemoryStream())
{
EmitResult emitResult = compilation.Emit(stream);
assembly = Assembly.Load(stream.GetBuffer());
}
Type ScriptClass = assembly.GetType("EnbuScript");
// Pass back the entire class so we can call it at the appropriate time.
return ScriptClass;
}
然后我试着这样称呼:
string Script = @"
using System;
using System.Data;
using System.IO;
using System.Linq;
public class EnbuScript
{
public string PostInsertRecord(CRMMobileFramework.EnbuUtils EnbuUtils,CRMMobileFramework.Includes.DBAdapter dbConn)
{
string ScriptTable = ""QuoteItems"";
DataSet EntityRecord = dbConn.FindRecord(""*"", ScriptTable, ""QuIt_LineItemID='"" + EnbuUtils.GetContextInfo(ScriptTable) + ""'"", """", 1, 1, false);
string OrderId = EntityRecord.Tables[""item""].Rows[0][""QuIt_orderquoteid""].ToString();
string UpdateOrderTotalCommand = ""UPDATE Quotes SET Quot_nettamt = (select SUM(QuIt_listprice * quit_quantity) from QuoteItems where quit_orderquoteid = "" + OrderId + "" ) where Quot_OrderQuoteID = "" + OrderId;
dbConn.ExecSql(UpdateOrderTotalCommand);
return ""Complete"";
}
}";
Type EnbuScript = EnbuUtils.EvalTableScript(Script, EnbuUtils, dbConn);
MethodInfo methodInfo = EnbuScript.GetMethod("InsertRecord");
object[] parameters = { EnbuUtils, dbConn };
string InsertRecordResult = methodInfo.Invoke(null, parameters).ToString();
如您所见,我一直在尝试将参数传递给编译。 基本上我有 4 个需要支持的函数,它们将以字符串形式出现。我要做的是为这 4 个函数创建一个类并编译和运行它们。这部分有效。 我现在需要做的就是将类实例传递给它。在代码中,您将看到一个 dbConn,它基本上是我的数据库连接。我需要将 this 的实例传递给我在运行时调用的方法,以便它具有正确的上下文。
我有另一个实现,我正在使用 Roslyn 会话。我最初尝试使用它并在运行时覆盖我的函数,但这也不起作用。请参阅下面我尝试过的内容:
public static void EvalTableScript(ref EnbuUtils EnbuUtils, DBAdapter dbConn, string EvaluateString)
{
ScriptEngine roslynEngine = new ScriptEngine();
Roslyn.Scripting.Session Session = roslynEngine.CreateSession(EnbuUtils);
Session.AddReference(EnbuUtils.GetType().Assembly);
Session.AddReference(dbConn.GetType().Assembly);
Session.AddReference("System.Web");
Session.AddReference("System.Data");
Session.AddReference("System");
Session.AddReference("System.XML");
Session.ImportNamespace("System");
Session.ImportNamespace("System.Web");
Session.ImportNamespace("System.Data");
Session.ImportNamespace("CRMMobileFramework");
Session.ImportNamespace("CRMMobileFramework.Includes");
try
{
var result = (string)Session.Execute(EvaluateString);
}
catch (Exception ex)
{
}
}
我尝试使用:
string PostInsertRecord = "" +
" public override void PostInsertRecord() " +
"{ " +
" string ScriptTable = \"QuoteItems\"; " +
"DataSet EntityRecord = dbConn.FindRecord(\"*\", ScriptTable, \"QuIt_LineItemID='\" + EnbuUtils.GetContextInfo(ScriptTable) + \"'\", \"\", 1, 1, false); " +
"string OrderId = EntityRecord.Tables[\"item\"].Rows[0][\"QuIt_orderquoteid\"].ToString(); " +
"string UpdateOrderTotalCommand = \"UPDATE Quotes SET Quot_nettamt = (select SUM(QuIt_listprice * quit_quantity) from QuoteItems where quit_orderquoteid = \" + OrderId + \" ) where Quot_OrderQuoteID = \" + OrderId; " +
"dbConn.ExecSql(UpdateOrderTotalCommand); " +
"} ";
该函数在 EnbuUtils 类中被声明为公共虚拟 void,但它说它没有合适的方法来覆盖。
可以肯定地说,我被难住了! 任何帮助表示赞赏! 谢谢
【问题讨论】:
标签: c# .net compilation runtime roslyn