MiniRazor
MiniRazor is a tiny wrapper around the Razor templating engine, which provides a way to compile and render templates on demand. This library focuses specifically on providing the lightest possible implementation that can be used in console, desktop, or other non-web applications.
Download
- NuGet:
dotnet add package MiniRazor
Features
- Easy to use, no need to configure Roslyn and Razor yourself
- Supports all C# features, including
async
/await
, local functions, and more - Supports internal types references within templates
- Supports dynamic, anonymous, or statically-defined models
- No dependency on
Microsoft.AspNetCore.App
shared framework or runtime - Works with .NET Standard 2.0+
Usage
Simple usage
The following example compiles a template and renders it using a model:
var engine = new MiniRazorTemplateEngine();
// Compile template (you may want to cache this instance)
var template = engine.Compile("<p>Hello, @Model.Subject!</p>");
// Render template
var result = await template.RenderAsync(new MyModel { Subject = "World" });
// -- result:
// <p>Hello, World!</p>
The entry point, MiniRazorTemplateEngine
is responsible for compiling Razor templates into IL code. Each compilation creates a new dynamic assembly, so it's strongly recommended to cache compiled templates as much as possible. You are free to choose how you want to do that.
Once compiled, the template can be rendered as many times as needed. Keep in mind that the RenderAsync
method is asynchronous to facilitate templates that contain asynchronous method invocations in them.
Anonymous model
You can also use an anonymous model as well:
var result = await template.RenderAsync(new { Foo = "Bar" });
Referencing internal types
Sometimes you may want to reference internal types in a template. Normally, since the template is compiled into a separate dynamic assembly in memory, it can't access internal types defined in other assemblies.
You can work around this, however, by using the InternalsVisibleTo
attribute on the assembly that contains those internal types. The assembly name generated by the template engine is not deterministic, but you can specify your own:
var engine = new MiniRazorTemplateEngine("RazorTemplateAssembly");
// ...
// Add this attribute to the assembly whose internal types you want to expose to the template
[assembly: InternalsVisibleTo("RazorTemplateAssembly")]
Custom namespace
To make it easier to reference types from your project, you can instruct the engine to compile the template code to a specific namespace.
For example, if you wanted to use a type from MyProject.Models
namespace, normally you would have to include a @using
directive:
@using MyProject.Models
@{
var a = new MyType();
}
But instead, you can configure MiniRazorTemplateEngine
with a custom root namespace:
var engine = new MiniRazorTemplateEngine("RazorTemplateAssembly", "MyProject.Models");
@{
var a = new MyType();
}
Note that the @using
directive is no longer necessary as both MyType
and the compiled template reside in the same namespace.
Statically-typed model
In order to have code completion inside a template, you need to let the IDE know what type of model it expects. In regular Razor templates you would do that via the @model
directive, however with MiniRazor you need to use @inherits
instead:
@inherits MiniRazor.MiniRazorTemplateBase<MyModel>
<p>Statically-typed model: @Model.Foo</p>
HTML-encoding
Output rendered with Razor templates is HTML-encoded by default. If you want to print raw HTML content, for example if it's sourced from somewhere else, you can use the Raw()
method:
@{
string GetHtml() => "<p>Hello world!</p>";
}
@GetHtml() // <p>Hello world!</p>
@Raw(GetHtml()) // <p>Hello world!</p>
Parent assembly
The MiniRazorTemplateEngine
object has a ParentAssembly
property, which is used to determine the compilation context for the templates. Any assembly referenced by the parent assembly is also referenced by the template assembly.
By default, the parent assembly is resolved as the assembly that called the MiniRazorTemplateEngine
constructor, but you can override this:
var parent = Assembly.Load("...");
var engine = new MiniRazorTemplateEngine(parent, "RazorTemplateAssembly");