c# - 使用 Microsoft.CodeAnalysis.CSharp.Scripting 动态执行 C# 失败
问题描述
我需要以字符串格式执行 C# 类并使用该类的属性填充对象。为了达到要求,我正在做 POC,但失败了。
以下代码无法评估我尝试更新输入模型的位置。
程序.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();
}
}
}
脚本管理器.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;
}
}
}
模型.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;
}
}
}
你有几个错误:
- 不使用
options
(第二个参数)Execute
- ctor 中的额外括号
- ctor 不应该有结果类型(
void
) input
属性未初始化- 创建类和使用它的脚本是分开的
推荐阅读
- android - Android TV 应用程序设计:视频细节和视频水平列表
- twig - 如何翻译变量?
- javascript - 为什么没有参数的测试在 Typescript 中失败?
- python - 查找标签列表和数据框索引之间的交集(Python Pandas)
- ansible - Jinja2 检查 lsit 是否为空
- javascript - JS RemoveEventListener 按类名来自动态添加的元素
- spring-boot - 声明列 TIME WITH TIME ZONE 时出现语法错误
- r - 以周计算时差
- javascript - 我想在我的表中插入一个按钮,当用户在搜索字段中搜索某些内容时使用 javascript 显示费用
- python - 如何修复错误以将字符串转换为 python 中的浮点数?