Getting Mono compiler output in a web application using StreamReportPrinter
I've been continuing my experiment with Mono's compiler as a service in an ASP.NET MVC application and making pretty good progress. One of the difficulties I ran into along the way was in troubleshooting compiler errors when I'd deployed the application. Almost all of the content and documentation on Mono.CSharp is in a console application / REPL scenario, which doesn't help in tracking down errors in a web application.
To recap from before, most of the samples you'll see for using Mono.CSharp look like this (undoubtedly copied from Miguel's blog):
var report = new Report(new ConsoleReportPrinter()); var evaluator = new Evaluator(new CompilerSettings(), report); evaluator.Run("DateTime.Now");
The problem is that the ConsoleReportPrinter writes to Console output, which isn't doing me any good.
// Mono.CSharp.ConsoleReportPrinter public override void Print(AbstractMessage msg) { base.Print(msg); if (base.Stacktrace) { Console.WriteLine(ConsoleReportPrinter.FriendlyStackTrace(new StackTrace(true))); } }
ConsoleReportPrinter's base is StreamReportPrinter, though, and that works just fine with a StringWriter, like this:
var reportWriter = new StringWriter(); try { var report = new Report(new StreamReportPrinter(reportWriter)); var evaluator = new Evaluator(new CompilerSettings(), report); evaluator.Run("using System.ComponentModel.DataAnnotations;"); evaluator.Run(modelDefinition); object model = evaluator.Evaluate("new Monkey();"); return View(model); } catch { string result = reportWriter.ToString(); return Content(result); }
Running this gives some useful output, indicating the compilation results:
{interactive}(1,30): error CS0234: The type or namespace name `DataAnnotations' does not exist in the namespace `System.ComponentModel'. Are you missing an assembly reference? {interactive}(1,30): error CS0234: The type or namespace name `DataAnnotations' does not exist in the namespace `System.ComponentModel'. Are you missing an assembly reference? {interactive}(1,6): error CS0246: The type or namespace name `Monkey' could not be found. Are you missing a using directive or an assembly reference?
Now that we've got the results as a string, they can be logged or handled appropriately.