Razorlight: NullReference Error using MemoryCaching to build engine

Created on 7 Dec 2019  路  12Comments  路  Source: toddams/RazorLight

Describe the bug
Hello, I am getting an error when I use the code in a .NET Core 3.1 project. I'm certain this happens in the .NET Core 3.0 project as well. System.ArgumentNullException: Value cannot be null. (Parameter 'razorLightProject')
at RazorLight.Compilation.RazorTemplateCompiler..ctor(RazorSourceGenerator sourceGenerator, RoslynCompilationService roslynCompilationService, RazorLightProject razorLightProject, RazorLightOptions razorLightOptions)
at RazorLight.RazorLightEngineBuilder.Build()

To Reproduce
Steps to reproduce the behavior:

  1. Use the following code to configure the Engine:
    var engine = new RazorLight.RazorLightEngineBuilder()
    .UseMemoryCachingProvider().Build();
    My assumption was that I would use the MemoryCachingProvider and everything should just work. However, it looks like the Build() method has a dependency on the "project" and the project parameter is null when Memory Caching is used.
    Please check around line 260 in this file: https://github.com/toddams/RazorLight/blob/master/src/RazorLight/RazorLightEngineBuilder.cs

Expected behavior
The engine should be created

Information (please complete the following information):

  • OS: Windows
  • Platform - .NET Core 3.1
  • RazorLight version - 2.0.0-beta2
  • Visual Studio version- VS 2019

All 12 comments

Same problem here. Please fix! Thank you,

I had thought about this, and I think this is actually a very narrow use case:

  1. The reason Project is effectively mandated is that without it you will eventually run into issues when you want to include partials, because how else do you expect RazorLight to locate your partial views if you don't have a Project that provides systematic resource location?
  2. Just create a project if you want a very narrow use case of passing in strings directly to render them.

How do I create a project? I am following the example you have for MemoryCaching on github and see no project.

https://github.com/toddams/RazorLight#how-to-use-templates-from-memory-without-setting-a-project

By the way, I do see the possibility of someone, say, storing templates as strings in a database. That's valid, but then you would implement your own project type. If you were doing this in the old version of RazorLight, I'd be a bit careful about using a database to store templates, as it's hard to write tests against dynamic production template data.

Thank you.

You might want to update your documentation to add Project to your first example and also change it to use CompileRenderStringAsync instead of CompileRenderAsync.

Thanks, i knew I missed something.

@ibasin Done. Could probably use some help / feedback on readability of the new README. My main goal was to stop the deluge of Issues into GitHub for known problems with known workarounds. I'm newer to RazorLight so it didnt dawn on me that most of these problems are "solved" and just that the solutions havent been communicated very well.

I added a regression test featuring the quickstart snippet called Ensure_QuickStart_Demo_Code_Works

This is great. Thank you for your support. The readme is pretty good now that the code in samples compiles. If I find any other issues, I will let you know.

Two more quick question:

1) Does Razor.Light support Master Pages? If not, is there a workaround?
2) Is Engine thread safe? Am I supposed to create just one engine for the entire web server and throw all rending jobs at that instance (that would be optimal from the performance/GC standpoint)?

Thank you in advance.

There are multiple ways to think about thread safety:

  1. Razor's underlying thread safety
  2. The stability of the C# Roslyn compiler across individual compiles - this is fairly robust but two compilations of the same Roslyn C# project can yield slightly difference results, which might make debugging issues hard if it turns out to be a bug in the Roslyn compiler
  3. Thead safety of the template cache provided by Microsoft.Extensions.Caching.Memory package
  4. RazorLight thread safety.

    1. Primary concern here is whether the OnCacheMissAsync call is properly protected.

    2. Secondary concern here is RoslynCompilationService and its use of Path.GetRandomFileName to give Roslyn a place to generate a dll for the compiled views. (Line 104 of RoslynCompilationService.cs) - string assemblyName = Path.GetRandomFileName(); - You'll get collisions here at around a hundred million file names due to the Birthday paradox, and fairly high chance of collisions at around a million file names. So, if you have about a million instances of RazorLight running on the same filesystem accessing the same current path and generating filenames for dlls, you're in trouble.

    3. DefaultRazorEngine.Instance seems thread safe in that I don't see it accessing any static variables.

    4. Locks on virtual methods (code that RazorLight does not own). None. This is safe.

    5. GetRuntimeProperties() calls - I checked, and it seems this is safe. I wasn't 100% sure what this would return for ExpandoObject, but it returns the plain interface, not the added properties.

In terms of making it safer, the RaceConditionTests.cs could be improved. -- This is the longest running test in the whole test suite but it actually doesnt verify much :( It would be nice to upgrade this test to use AutoFixture.

  1. Does Razor.Light support Master Pages? If not, is there a workaround?

Please search the tests for _Layout.cshtml

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Wolftousen picture Wolftousen  路  5Comments

diegobrum picture diegobrum  路  5Comments

Hubert-Rybak picture Hubert-Rybak  路  5Comments

WaltDaniels picture WaltDaniels  路  6Comments

shobman picture shobman  路  4Comments