首页 文章

编译C#Roslyn

提问于
浏览
-1

我正在使用Roslyn尝试在运行时编译和运行代码 . 我已经看到了一些我在网上找到的代码,并且有些工作 .

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,它基本上是我的数据库连接 . 我需要将此实例传递给我在运行时调用的方法,因此它具有正确的上下文 .

我有另一个实现,我正在使用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,但它表示它没有合适的方法来覆盖 .

可以说,我很难过!任何帮助赞赏!谢谢

1 回答

  • -1

    我最终得到了这个 - 第一种方法非常接近我实际需要的方法 . 将方法更改为static并且必须添加一些引用,包括完整命名空间 .

相关问题