I use razor engine like this:
public class EmailService : IService
{
private readonly ITemplateService templateService;
public EmailService(ITemplat
I needed to supply my own layout as either a string or a file name. Here is how I solved this (based on this blog post)
public static class RazorEngineConfigurator
{
public static void Configure()
{
var templateConfig = new TemplateServiceConfiguration
{
Resolver = new DelegateTemplateResolver(name =>
{
//no caching cause RazorEngine handles that itself
var emailsTemplatesFolder = HttpContext.Current.Server.MapPath(Properties.Settings.Default.EmailTemplatesLocation);
var templatePath = Path.Combine(emailsTemplatesFolder, name);
using (var reader = new StreamReader(templatePath)) // let it throw if doesn't exist
{
return reader.ReadToEnd();
}
})
};
RazorEngine.Razor.SetTemplateService(new TemplateService(templateConfig));
}
}
Then I call RazorEngineConfigurator.Configure() in Global.asax.cs and it's ready.
The path to my templates is in Properties.Settings.Default.EmailTemplatesLocation
In my view I have this:
@{ Layout = "_layout.html";}
_layout.html is in emailsTemplatesFolder
It's a pretty standard HTML with a @RenderBody() call in the middle.
As far as I understand, RazorEngine uses the template name ("_layout.html" in this case) as a key to its cache so the delegate in my configurator is called only once per template.
I think it uses that resolver for every template name it doesn't know (yet).