2011-05-17 49 views
2

我很想知道如何实现我正在开发的一个项目的关键部分。本质上它是数据映射,在这里我复制字段x并将其放入字段y中。但是,在转换过程中需要有一些动态更改(使用字符串操作)该值的功能。c#和动态字符串脚本

我想要的是一个用户可以输入脚本的文本框,允许他们使用脚本语言(最好是VBScript)修改该值。然后,让他们做简单的操作,例如这个例子中,这将需要一个字符串:

Mid({input_value}, 2, 4) 

{input_value} 

会在运行时的实际值来代替。例如,如果来自“field x”的输入是“This is a test”并且他们使用上述的start = 2和length = 4的示例,则保存到“field y”中的值将是“他的“

我知道如何从C#运行VBScript作为scipt,这不是问题。但是,是否可以在运行时运行和评估上述srcipts,并将输出记录回C#变量?

否则,有没有人有任何建议我可以如何解决这个问题?

非常感谢

回答

1

你可能想看看像IronPython的或IronRuby的一个DLR为基础的语言。两者都允许嵌入,并且Michael Foord有关于如何在应用程序中嵌入这些内容的tutorial

如果您使用标准的DLR接口,我相信您可以嵌入任何语言,包括DLRBasicASP Classic Compiler。 Ben Hall在Red Gate的产品申请中有关于IronRuby embedding的文章。

我认为你需要从脚本查看设置的例子如下所示SetVariable()和的getVariable()方法,并返回数据:

public string evaluate(string x, string code) 
{ 
    scope.SetVariable("x", x); 
    scope.SetVariable("button", this.button); 

    try 
    { 
     ScriptSource source = engine.CreateScriptSourceFromString(code, 
      SourceCodeKind.Statements); 

     source.Execute(scope); 
    } 
    catch (Exception ex) 
    { 
     return "Error executing code: " + ex.ToString(); 
    } 

    if (!scope.VariableExists("x")) 
    { 
     return "x was deleted"; 
    } 
    string result = scope.GetVariable<object>("x").ToString(); 
    return result; 
} 

这个例子是从http://www.voidspace.org.uk/ironpython/dlr_hosting.shtml拍摄。

+0

谢谢你的帖子,我正在看这些选项。 – Adam 2011-05-17 02:37:00

+0

但是我确实有一个问题 - 可以动态地运行脚本,但是可以从IronRuby/IronPython返回一个返回到C#变量的结果吗? – Adam 2011-05-17 02:38:01

+0

应该是。我想你应该看看.NET 4.0上的C#'dynamic'关键字。在早期版本的.NET上应该有一个解决方案,但我需要查看它。 – 2011-05-17 02:40:50

0

这是一个使用运行时编译表达式的工作示例。我借用了这个概念和大部分代码from here

static void Main(string[] args) 
{ 
    string input = "This is a test"; 
    string method = "Mid(x, 2, 4)"; // 'x' represents the input value 
    string output = Convert(method, input); 
    Console.WriteLine("Result: " + output); 
    Console.ReadLine(); 
} 

// Convert input using given vbscript logic and return as output string 
static string Convert(string vbscript, string input) 
{ 
    var func = GetFunction(vbscript); 
    return func(input); 
} 

// Create a function from a string of vbscript that can be applied 
static Func<string, string> GetFunction(string vbscript) 
{ 
    // generate simple code snippet to evaluate expression 
    VBCodeProvider prov = new VBCodeProvider(); 
    CompilerResults results = prov.CompileAssemblyFromSource(
     new CompilerParameters(new[] { "System.Core.dll" }), 
     @" 
Imports System 
Imports System.Linq.Expressions 
Imports Microsoft.VisualBasic 

Class MyConverter 

Public Shared Function Convert() As Expression(Of Func(Of String, String)) 
    return Function(x) " + vbscript + @" 
End Function 

End Class 
" 
     ); 

    // make sure no errors occurred in the conversion process 
    if (results.Errors.Count == 0) 
    { 
     // retrieve the newly prepared function by executing the code 
     var expr = (Expression<Func<string, string>>) 
      results.CompiledAssembly.GetType("MyConverter") 
       .GetMethod("Convert").Invoke(null, null); 
     Func<string, string> func = expr.Compile(); 

     // create a compiled function ready to apply and return 
     return func; 
    } 
    else 
    { 
     return null; 
    } 
}