Use-cases
- Email server that uses Razor for its Email templates
- Console application without a web-site
Solution
- Build a very minimal web application with Razor support
- Don't start the web application
- Add services from the Razor app to your main app
Why this solution
- To compile Razor templates, you need a LOT of dependencies
- Most of these are part of ASP.NET Web Application
- Converting your application to a Web Application means it will also start listening to HTTP requests
- You may not want this for security and performance reasons
- Even when resolving all dependencies manually (without using web host), the ViewEngine is still not be able to locate the templates
Implementation
Creating a minimal WebApplication that can compile Razor, without running any web server.
WebApplication CreateRazorApp()
{
var builder = WebApplication.CreateBuilder();
builder.Services
.AddRazorPages()
.AddApplicationPart(typeof(EmailTemplates).Assembly); // Import views from another assembly
return builder.Build();
}
Taking some services from the Razor App and injecting them into a ViewRenderer, for use in the main app
services.AddSingleton<ViewRenderer>(_ => {
var webApp = CreateRazorApp();
return new ViewRenderer(
// The view renderer requires a scoped service provider to resolve some scoped services
webApp.Services.CreateScope().ServiceProvider,
webApp.Services.GetRequiredService<IRazorViewEngine>(),
webApp.Services.GetRequiredService<ITempDataProvider>());
});
The ViewRenderer itself
See ViewRenderer.cs
Usage
Here's a fake example of how you might use the IViewRenderer
to render a template and send it as an email.
class EmailSender {
private ViewRenderer viewRenderer;
public SomeService(IViewRenderer viewRenderer) {
this.viewRenderer = viewRenderer;
}
public SendWelcomeMail() {
MailHelper.SendMail("[email protected]", await viewRenderer.RenderAsync("EmailTemplates/welcome", new EmailData {
To = "John Doe"
});
}
}