OdeToCode IC Logo

Spying on Razor View Compilation

Wednesday, February 3, 2016

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
            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;

    <h3>Compilation Results</h3>

    @foreach (var result in GetCompilationSpy().CompilationLog)



Which yields output like the following:


Comments are closed.