Is there a way to dynamically execute code contained in a string using .net 2.0, in a similar way to eval() in javascript or using sp_executeSQL in tsql?
I have a st
It's not tooo hard ;) I put together a little example. This should help you decide if you want to use dynamic scripts.. or regexes.
What you can do is create an interface in your assembly, which your dynamic code will implement:
namespace CompileScriptExample
{
public interface IStringManipulator
{
string processString(string aString);
}
}
Then create a ScriptRunner class:
namespace CompileScriptExample
{
public class ScriptRunner
{
public static string RunScript(string scriptCode, string scriptParameter)
{
CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
//configure parameters
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateExecutable = false;
parameters.GenerateInMemory = true;
parameters.IncludeDebugInformation = false;
string reference;
// Set reference to current assembly - this reference is a hack for the example..
reference = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
parameters.ReferencedAssemblies.Add(reference+"\\CompileScriptExample.exe");
//compile
CompilerResults results = provider.CompileAssemblyFromSource(parameters, new string[] { scriptCode });
if (results.Errors.Count == 0)
{
IStringManipulator compiledScript=(IStringManipulator)FindInterface(results.CompiledAssembly, "IStringManipulator");
return compiledScript.processString(scriptParameter);//run the script, pass the string param..
}
else
{
foreach(CompilerError anError in results.Errors)
{
MessageBox.Show(anError.ErrorText);
}
//handle compilation errors here
//..use results.errors collection
throw new Exception("Compilation error...");
}
}
private static object FindInterface(Assembly anAssembly, string interfaceName)
{
// find our interface type..
foreach (Type aType in anAssembly.GetTypes())
{
if (aType.GetInterface(interfaceName, true) != null)
return anAssembly.CreateInstance(aType.FullName);
}
return null;
}
}
}
Now all you have to do is create a script string with code that implements your interface like..
string myScriptString=@"using CompileScriptExample;
public class MyStringManipulator : IStringManipulator
{
public string processString(string aString)
{
return aString+aString;
}
};
and then.. in your code, make use of the ScriptRunner to process your string with your dynamic code:
string processedString = ScriptRunner.RunScript(myScriptString, "hello");
I just ran across something the other day which does just this in another .NET language: http://reverseblade.blogspot.com/2009/02/dont-wait-for-c-5-use-nemerle.html
I would imagine you could write your string-processing code in nemerle, compile, and reference from your C# or VB app.
I would still favor an extensible design like casperOne suggests. By doing dynamic scripting, you'll just be pushing compilation into the app and deployment into whatever process gets the programming strings to the app. But it sounds like you have your reasons, so the only other thing I'd consider here is security. Ideally, you want to limit the user as much as possible to just manipulating strings, in which case List-of-Regex seems like a pretty good option.