2016-02-19 1 views
4

Я пытаюсь выяснить вопрос, мы имели в последнее время с RazorEngine 3.7.5 и выше (пробовал 3.7.7)RazorEngine 3.7.7 - Ошибка при компиляции в кэше шаблона

Исключение:

System.ArgumentException: Пожалуйста, либо установите диспетчер шаблонов в шаблоны, либо добавьте шаблон «MySolution.Billing.Templates.Layout.cshtml»!

Это происходит при попытке кэширования шаблона с помощью метода Engine.Razor.Compile.

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); 
} 

Метод PreloadTemplates вызывается, когда служба, содержащая его, создается с использованием StructureMap для instanciation. Каждый шаблон хранится как встроенный ресурс и загружается в кеш RazorEngine и сразу же после этого скомпилирован с использованием RazorEngine, чтобы убедиться, что все шаблоны загружаются как можно быстрее.

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 сконфигурирован как следовать

var config = new TemplateServiceConfiguration(); 
config.CachingProvider = new DefaultCachingProvider(t => { }); 
config.DisableTempFileLocking = true; 

Как мы используем RazorEngine, поток приложения

  1. WCF (InvoiceQueryFacade)
    • Global.asax. Регистры cs Реестры StructureMap
  2. IInvoiceService (инстанциирован по StructureMap обеспечить InvoiceService)
    • Служба называет PreloadTemplates в это конструктор

Действия по воспроизведению

Мы можем воспроизвести ошибка почти каждый раз, останавливая IIS и запуская его снова и doin g a вызов метода WCF. Кажется, что проблема связана с переработкой пула приложений или остановкой IIS, потому что ошибка не возвращается после того, как WCF «разогрелся».

ответ

5

Я смог найти ответ сам после всего.

Я изменил мой класс TemplatingService следующим

public class TemplatingService : ITemplatingService 
{ 
    private readonly IRazorEngineService _razorEngineService; 

    public TemplatingService(Assembly assembly, string templatesNamespace) 
    { 
     var config = new TemplateServiceConfiguration(); 
     config.TemplateManager = new EmbeddedResourceTemplateService(assembly, templatesNamespace); 

#if DEBUG 
     config.Debug = true; 
#endif 

     this._razorEngineService = RazorEngineService.Create(config); 
    } 

    public void CacheTemplate(string templateName, Type type) 
    { 
     var templateKey = new NameOnlyTemplateKey(templateName, ResolveType.Layout, null); 
     this._razorEngineService.Compile(templateKey, type); 
    } 

    public string RunTemplate(string templateName, Type type, object model, IDictionary<string, object> dynamicViewBag = null) 
    { 
     var templateKey = new NameOnlyTemplateKey(templateName, ResolveType.Layout, null); 
     return this._razorEngineService.RunCompile(templateKey, type, model, dynamicViewBag != null ? new DynamicViewBag(dynamicViewBag) : null); 
    } 
} 

Я начал использовать TemplatingManager с официального сайта: RazorEngine string layouts and sections? и, казалось, сделали свое дело.

this.For<ITemplatingService>() 
      .Singleton() 
      .Add<TemplatingService>() 
      .Named("invoiceTemplates") 
      .Ctor<Assembly>("assembly").Is(billingDocumentGeneratorAssembly) 
      .Ctor<string>("templatesNamespace").Is("MyBillingNamespace.DocumentGenerator.Invoices.Templates"); 

И я могу использовать TemplatingService следующим

var footerHtml = this._templatingService.RunTemplate("Footer.cshtml", null, null); 
var headerHtml = this._templatingService.RunTemplate("Header.cshtml", typeof(AccountStatementHeaderModel), accountStatementModel.Header); 

Я надеюсь, что эта помощь кому-то еще.