Sometimes the best way to understand code is to compile and execute the code. In this scenario I needed to understand a bit more about view compilation in ASP.NET Core. Here is a simple spy to track the file information and compilation results for each razor view.
public class RazorCompilationServiceSpy : IRazorCompilationService
{
private IRazorCompilationService _inner;
private IList<CompileEntry> _log;
public RazorCompilationServiceSpy(ICompilationService compilationService,
IMvcRazorHost razorHost,
IOptions<RazorViewEngineOptions> options)
{
_inner = new RazorCompilationService(compilationService, razorHost, options);
_log = new List<CompileEntry>();
}
public CompilationResult Compile(RelativeFileInfo fileInfo)
{
var result = _inner.Compile(fileInfo);
_log.Add(new CompileEntry { FileInfo = fileInfo, Result = result });
return result;
}
public IEnumerable<CompileEntry> CompilationLog
{
get
{
return _log;
}
}
public class CompileEntry
{
public RelativeFileInfo FileInfo { get; set; }
public CompilationResult Result { get; set; }
}
}
The easiest way to grab information from the class is to register the class as a singleton during Startup::Configure.
services.AddSingleton<IRazorCompilationService, RazorCompilationServiceSpy>();
Note that the real RazorCompilationService runs as a transient service in a typical ASP.NET application, but for this simple experiment we are ignoring all the terrible threading problems that might arise using singletons and regular collection classes like a List<T>.
Inside a Razor view we can use the following code to see the compilation results.
@using Microsoft.AspNet.Mvc.Razor.Compilation;
@inject IRazorCompilationService CompilationSpy
@functions {
public RazorCompilationServiceSpy GetCompilationSpy()
{
return (RazorCompilationServiceSpy)CompilationSpy;
}
}
<section>
<h3>Compilation Results</h3>
@foreach (var result in GetCompilationSpy().CompilationLog)
{
<h4>@result.FileInfo.RelativePath</h4>
<pre>@result.Result.CompiledContent</pre>
}
</section>
Which yields output like the following:
OdeToCode by K. Scott Allen