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.

No Comments