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;
}
}
精彩评论