2011-05-17 32 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; 
    } 
}