开发者

c# and dynamic string scripting

I'd love some ideas about how I should implement a key part of a project I am working on. Essentially it is data mapping, where I copy field x and put it into field y. However, there needs to be some ability to dynamically change (using string manipulation) that value during the transition.

What I would like is a textbox where a user could enter script allowing them to modify that value using a scripting language, ideally VBScript. That would then allow them to do simple man开发者_如何学Cipulations such this example, which would take a substring:

Mid({input_value}, 2, 4)

Where

{input_value} 

Would be replaced by the actual value at runtime.

So, for example, if the input from "field x" was "This is a test" and they used the above example of start = 2 and length = 4, the value saved into "field y" would be "his "

I know how I could run VBScript from C# as a scipt, that's not a problem. However, Is it possible to run and evaluate srcipts such as above at runtime and record the output back into a C# variable?

Otherwise, does anyone have any suggestions about how I could approach this?

Many thanks


You might want to look at a DLR-based language like IronPython or IronRuby. Both allow embedding and Michael Foord has a tutorial on how to embed these in an application.

If you use the standard DLR interfaces I believe you can embed any language including DLRBasic and the ASP Classic Compiler. Ben Hall has an article on IronRuby embedding in a production application for Red Gate.

I think you need to review the SetVariable() and GetVariable() methods shown below for an example of setting and return data from scripts:

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;
}

This example was taken from http://www.voidspace.org.uk/ironpython/dlr_hosting.shtml.


Here is a working example using runtime compilation of expressions. I borrowed the concept and most of the code 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;
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜