Search code examples
c#.netrazor.net-6.0razor-class-library

Hot Reload of .cshtml files within a Razor Class Library (or any solution to avoid Rebuild)


I have a bare bones razor pages project targeting the net6.0 framework using Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 6.0.11 (Microsoft.NET.Sdk.Web).

It consumes a Razor Class Library, also targeting net6.0 (Microsoft.NET.Sdk.Razor).

Both projects are in the same solution in VS 2022 Pro.

I am using minimal build:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages().AddRazorRuntimeCompilation();
builder.Services.Configure<MvcRazorRuntimeCompilationOptions>(options => {
    var libraryPath = System.IO.Path.GetFullPath(System.IO.Path.Combine(builder.Environment.ContentRootPath, "..", "razor.platform.thehub.cloud"));
    options.FileProviders.Add(new PhysicalFileProvider(libraryPath));
});

var app = builder.Build();
app.UseStaticFiles();
app.MapRazorPages();
app.Run();

The project builds and consumes the razor class library perfect fine. Razor pages, wwwroot content all work perfectly in the consuming app. Breakpoints work fine in the RCL and changes to any RCL wwwroot content prompts a hot reload as expected (css, js etc).

My only issue is with .cshtml in the RCL (Pages). Any changes to them prompts a hot reload as expected, so VS debugging is detecting a code change and confirms that 'Code changes were applied successfully'. However, the changes to the .cshtml file in the RCL are not shown. I have to rebuild and restart the local debugging session to see them.

I'm convinced I've been able to do this in the past (Core 2/3), but I may be imagining it!

Any help greatly appreciated.


Solution

  • I was also wondering the same. The feature that existed in the past was called "razor runtime compilation". According to official docs:

    Enable runtime compilation with the instructions at Conditionally enable runtime compilation in an existing project.

    Configure the runtime compilation options in Startup.ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
    
        services.Configure<MvcRazorRuntimeCompilationOptions>(options =>
        {
            var libraryPath = Path.GetFullPath(
                Path.Combine(HostEnvironment.ContentRootPath, "..", "MyClassLib"));
            options.FileProviders.Add(new PhysicalFileProvider(libraryPath));
        });
    }
    

    In the preceding code, an absolute path to the MyClassLib RCL is constructed. The PhysicalFileProvider API is used to locate directories and files at that absolute path. Finally, the PhysicalFileProvider instance is added to a file providers collection, which allows access to the RCL's .cshtml files.