I'm trying to write an interactive C# teaching app, where the user can experiment/change code examples and see what happens (kinda like jsfiddle).
I've found a lot of examples for small expressions or REPL-like uses of Mono.Csharp as runtime compiler, but I can't quite find an example where a "mini program" is executed.
Here's my toy code so far (an MVC action). The "code" parameter is posted straight from a textarea.
[HttpPost]
public ActionResult Index(string code)
{
var reportWriter = new StringWriter();
var settings = new CompilerSettings();
var printer = new ConsoleReportPrinter(reportWriter);
var reports = new Report(printer);
var eval = new Evaluator(settings, reports);
var model = new CodeViewModel();
model.Code = code;
eval.Run(code);
model.Result = reportWriter.ToString();
return View("Index", model);
}
Now suppose the code is a string like this:
using System;
public class MyClass
{
public void DoSomething()
{
Console.WriteLine("hello from DoSomething!");
}
}
How do I bootstrap this (i.e. instantiate a MyClass
object and call DoSomething
on it)? I've tried just appending new MyClass().DoSomething();
to the end, but I get this:
{interactive}(1,2): warning CS0105: The using directive for `System' appeared previously in this namespace
{interactive}(1,8): (Location of the symbol related to previous warning)
{interactive}(11,1): error CS1530: Keyword `new' is not allowed on namespace elements
{interactive}(11,4): error CS1525: Unexpected symbol `MyClass', expecting `class', `delegate', `enum', `interface', `partial', or `struct'
What am I missing?
var reportWriter = new StringWriter();
var settings = new CompilerSettings();
var printer = new ConsoleReportPrinter(reportWriter);
var reports = new Report(printer);
var eval = new Evaluator(settings, reports);
eval.Run(code);
eval.Run(@"
var output = new System.IO.StringWriter();
Console.SetOut(output);
new MyClass().DoSomething();");
var model = new CodeViewModel();
model.Code = code;
if (reports.Errors > 0)
model.Result = reportWriter.ToString();
else
model.Result = (string) eval.Evaluate("output.ToString();");
return View("Index", model);