I am trying to find out the problem that we have recently encountered with RazorEngine 3.7.5 and higher (tried 3.7.7)
An exception:
System.ArgumentException: either install the template manager in the templates, or add the template "MySolution.Billing.Templates.Layout.cshtml"!
This occurs when trying to cache a template using the 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 a service containing it is created using StructureMap for instanciation. Each template is stored as an embedded resource and loaded into the RazorEngine cache, and immediately after that compiled using RazorEngine to make sure that all templates are loaded as quickly 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 follows
var config = new TemplateServiceConfiguration(); config.CachingProvider = new DefaultCachingProvider(t => { }); config.DisableTempFileLocking = true;
How we use RazorEngine, application thread
- WCF (InvoiceQueryFacade)
- Global.asax.cs registers StructureMap registries.
- IInvoiceService (created by StructureMap to provide InvoiceService)
- A service calls PreloadTemplates in it constructor
Playback Steps
We can reproduce the error almost every time by stopping IIS and starting it again and calling the WCF method. It seems that the problem is with processing the application pool or stopping IIS, because the error does not return after the WCF has βwarmed upβ.