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: