I'm trying to figure out an issue we've been having lately with RazorEngine 3.7.5 and higher (tried 3.7.7)
Exception:
System.ArgumentException: Please either set a template manager to templates or add the template 'MySolution.Billing.Templates.Layout.cshtml'!
It occurs when trying to cache the template with Engine.Razor.Compile method.
public void AddTemplate(string templateName, string source)
{
Engine.Razor.AddTemplate(templateName, source);
}
public void CacheTemplate(string templateName, Type type)
{
var templateKey = new NameOnlyTemplateKey(templateName, ResolveType.Layout, null);
Engine.Razor.Compile(templateKey, type);
}
The PreloadTemplates method is called when the service which contains it is created using StructureMap for instanciation. Each templates is stored as an Embedded Resource and loaded into RazorEngine cache and immediatly after that compiled using RazorEngine to make sure that all templates load as quick as possible.
private void PreloadTemplates()
{
var embeddedResources = Assembly.GetExecutingAssembly().GetManifestResourceNames().Where(x => x.StartsWith("MySolution.Billing.Templates")).ToList();
foreach (var invoiceResource in embeddedResources)
{
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(invoiceResource))
{
using (var reader = new StreamReader(stream))
{
var template = reader.ReadToEnd();
this._templatingService.AddTemplate(invoiceResource, template);
}
}
}
this._templatingService.CacheTemplate("MySolution.Billing.Templates.Header.cshtml", typeof(HeaderModel));
this._templatingService.CacheTemplate("MySolution.Billing.Templates.Layout.cshtml", typeof(LayoutModel));
this._templatingService.CacheTemplate("MySolution.Billing.Templates.Footer.cshtml", null);
}
RazorEngine is configured as follow
var config = new TemplateServiceConfiguration();
config.CachingProvider = new DefaultCachingProvider(t => { });
config.DisableTempFileLocking = true;
How we are using RazorEngine, flow of the application
- WCF (InvoiceQueryFacade)
- Global.asax.cs registers StructureMap registries
- IInvoiceService (Instanciated by StructureMap to provide an InvoiceService)
- The service calls PreloadTemplates in it's constructor
Steps to reproduce
We can reproduce the error almost everytimes by stopping IIS and starting it back again and doing a a call to the WCF method. It seems to be a problem with recycling the app pool or stopping IIS because the error does not come back after WCF has "warmed up".