动态执行c#与Microsoft.CodeAnalysis.CSharp.Scripting失败 &



我需要以字符串格式执行一个c#类,并用该类的属性填充一个对象。为了达到这个要求,我做了一个POC,但失败了。

下面的代码无法评估我试图更新输入模型的位置。

Program.cs

using Microsoft.CodeAnalysis.CSharp.Scripting;
using System;
namespace CSCodeExecuter
{
class Program
{
static void Main(string[] args)
{
Model input = new Model();
string scriptId = "123";
ScriptManager sriptMgr = new ScriptManager();
sriptMgr.ExecuteScript<Model>(scriptId, ref input);
Console.WriteLine(input.ToString());
Console.ReadKey();
}
}
}

ScriptManager.cs

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CSCodeExecuter
{
public class ScriptManager
{
public void ExecuteScript<T>(string scriptId, ref T input)
{
try
{
string inputSript = GetStriptById(scriptId);
var scriptOptions = ScriptOptions.Default;
scriptOptions.AddReferences("CSCodeExecuter");

Execute(inputSript, scriptOptions);
var result = Execute("new ScriptedClass().input", scriptOptions);
}
catch (Exception ex)
{
throw;
}

}
private string GetStriptById(string id)
{

string csSript = @" public class ScriptedClass
{
public CSCodeExecuter.Model input {get;set;}
public void ScriptedClass()
{
{" + GetInternalScript() + @"}
}
}";
return csSript;
}
private string GetInternalScript()
{
return "input.Id = "1111"; " + "input.Name = "test"; " + "input.Phone = "1234567890"; ";
}

private static ScriptState<object> scriptState = null;
public static object Execute(string code, dynamic scriptOptions)
{
scriptState = scriptState == null ? CSharpScript.RunAsync(code).Result : scriptState.ContinueWithAsync(code).Result;
if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString()))
return scriptState.ReturnValue;
return null;
}
}
}

Model.CS

namespace CSCodeExecuter
{
public class Model
{
public string Id { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}
}

现在可以运行了:

using System;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
namespace CSCodeExecuter
{
public class ScriptManager
{
public void ExecuteScript<T>(string scriptId, ref T input)
{
try
{
string inputSript = GetStriptById(scriptId);
var scriptOptions = ScriptOptions.Default.AddReferences("CSCodeExecuter");
var result = Execute(inputSript, scriptOptions);
}
catch (Exception ex)
{
throw;
}
}
private string GetStriptById(string id)
{
string csSript =
@"
public class ScriptedClass
{
public CSCodeExecuter.Model input {get;set;}
public ScriptedClass()
{
" + GetInternalScript() + @"
}
}
return (new ScriptedClass()).input;";
return csSript;
}
private string GetInternalScript()
{
return "input = new CSCodeExecuter.Model(); input.Id = "1111"; input.Name = "test"; input.Phone = "1234567890"; ";
}

private static ScriptState<object> scriptState = null;
public static object Execute(string code, dynamic scriptOptions)
{
scriptState = scriptState == null ? CSharpScript.RunAsync(code, scriptOptions).Result : scriptState.ContinueWithAsync(code).Result;
if (scriptState.ReturnValue != null && !string.IsNullOrEmpty(scriptState.ReturnValue.ToString()))
return scriptState.ReturnValue;
return null;
}
}
}

你有几个错误:

  1. 不使用options(第二个参数)在Execute
  2. 中添加括号
  3. 不应该有结果类型(void)
  4. input属性未初始化
  5. 脚本与类的创建和使用是分开的

最新更新