2012-05-09 12 views
11

जब आप RazorEngine.Razor.Compile() पर कॉल करते हैं, तो संकलित टेम्पलेट कहां संग्रहीत किया जाता है?रैजोरइंजिन में टेम्पलेट कैसे कैश किए जाते हैं?

क्या यह कार्यक्रम पुनरारंभ होने के बाद उपलब्ध है? अगर स्मृति की कमी है, तो इसे डंप किया जाएगा?

मैं RazorEngineASP.NET (MVC) प्रोजेक्ट में उपयोग कर रहा हूं। एप्लिकेशन पुनरारंभ होने के बाद प्रीकंपिल्ड टेम्पलेट्स उपलब्ध होंगे?

क्या HttpContext.Cache में उन्हें स्टोर करने के लिए मुझे और अधिक समझदारी होगी? यदि मैंने किया, तो क्या यह एक अलग फ़ंक्शन (Compile के अलावा) का उपयोग करने के लिए अधिक समझ में आता है जो आंतरिक कैश को छोड़ देता है? क्या ITemplate निष्पादित करने का कोई तरीका है और बस इसे एक मॉडल पास करें?

क्या RazorEngine.Razor.Parse() कोई कैशिंग है? या टेम्पलेट हर बार recompiled है?

उत्तर

16

वर्तमान में, रेजोरइंजिन टेम्पलेट को संकलित करने के बाद, वे स्मृति में लोड हो जाते हैं। ये असेंबली केवल स्मृति में बनी रहती हैं और आवेदन के जीवनकाल से आगे नहीं बढ़ती हैं।

मैं इन असेंबली को फ़ाइलों में संकलित करने के लिए समर्थन जोड़ने पर विचार कर रहा हूं, लेकिन यह भविष्य का संस्करण होगा।

आप Razor.Parse फोन और टेम्पलेट के लिए एक नाम पर पार कर लेते हैं, यह

  1. करने का प्रयास करेंगे ही नाम के साथ एक विधानसभा के लिए इन-स्मृति विधानसभाओं के कैश की जाँच करें।
  2. टेम्पलेट की सामग्री का अमान्य बदल गया है।
  3. नए संकलित टेम्पलेट को कैश करें।
+0

मेरे प्रश्न का उत्तर देने के लिए बहुत बहुत धन्यवाद। मुझे नहीं पता कि मैंने कभी यह क्यों नहीं देखा। तो अगर और केवल अगर मैं रेजर को नाम पास करता हूं। पर्स और टेम्पलेट पिछले समय के समान है जिसे मैंने रेजर कहा था। उसी नाम के साथ पर्स। फिर यह एक नया निर्माण करने के बजाय कैश असेंबली का उपयोग करेगा? – Rabbi

+0

@ रब्बी हां, यह इस तरह काम करता है। टेम्पलेट के नाम पर गुजरते समय, हम टेम्पलेट सामग्री के हैशकोड को पकड़ते हैं और गतिशील रूप से संकलित प्रकार के साथ मेमोरी कैश में स्टोर करते हैं। अगली बार जब आप इसे कॉल करते हैं, तो टेम्पलेट स्ट्रिंग का हैशकोड नहीं बदला है, तो हम टेम्पलेट प्रकार को तुरंत चालू कर सकते हैं और इसे निष्पादित कर सकते हैं। यदि नहीं, तो हम मौजूदा प्रकार को कैश में अमान्य कर देते हैं और नई टेम्पलेट सामग्री पर आधार को पुन: संकलित करते हैं। –

+3

एफवाईआई, यह नहीं है कि यह वर्तमान RazorEngine में कैसे काम करता है। प्रोफाइलिंग ने रेजर को दिखाया। पर्स ने प्रत्येक वेब कॉल में 2 सेकंड देरी की। इसे Razor.GetTemplate() के साथ स्विच करना; Razor.Run(); सही ढंग से हमारे लिए कैशिंग ट्रिगर किया। – KallDrexx

6

मैं इस RazorEngine 3.4.1.0 के साथ काम मिल गया है, देर से जनवरी 2014

कुंजी महंगा Razor.Compile(content, name) कॉल करने के लिए कैश में टेम्पलेट डाल करने के लिए है, तो सस्ते Razor.Run(name, model) फोन पर अमल करने के लिए स्थापित नमूना।

याद रखें कि टेम्पलेट सामग्री पढ़ना महंगा हो सकता है - कहें, डिस्क से पढ़ने को शामिल करना - इसलिए मेरा समाधान केवल एक बार टेम्पलेट सामग्री प्राप्त करता है। यह आपके लिए बहुत अधिक कैशिंग हो सकता है, इसलिए सावधान रहें!

यहां RenderPartial विधि है जिसका उपयोग मैं कस्टम TemplateBase<T> सबक्लास के अंदर करता हूं। यह एक ही टेम्पलेट पर एकाधिक कॉल के लिए बहुत तेज़ी से चलता है।

public abstract class SqlTemplate<T>: TemplateBase<T> 
{ 
    public string RenderPartial(string templateName, object model = null) 
    { 
     // loading a template might be expensive, so be careful to cache content 
     if (Razor.Resolve(templateName) == null) 
     { 
      // we've never seen this template before, so compile it and stick it in cache. 
      var templateContent = GetTemplateContent(templateName); 
      Razor.Compile(templateContent, templateName); 
     } 

     // by now, we know we've got a the template cached and ready to run; this is fast 
     var renderedContent = Razor.Run(templateName, model); 
     return renderedContent; 
    } 

    private string GetTemplateContent(string templateName) 
    { 
     ... your implementation here 
    } 
} 

तुम भी RazorEngineConfigurator.Configure() को फोन करके इस आधार वर्ग (SqlTempalte<T>) जो आप इस तरह कर सकते हैं, उपयोग करने के लिए रेजर बताने के लिए की जरूरत है;

public static class RazorEngineConfigurator 
{ 
    private static bool configured = false; 

    public static void Configure() 
    { 
     if (configured) 
     { 
      return; 
     } 

     var templateConfig = new TemplateServiceConfiguration 
     { 
      BaseTemplateType = typeof(SqlTemplate<>), 
      EncodedStringFactory = new RazorEngine.Text.RawStringFactory() 
     }; 

     RazorEngine.Razor.SetTemplateService(new TemplateService(templateConfig)); 

     configured = true; 
    } 
} 

this SO answer के बिना यह नहीं कर सकते थे - क्यों एक अप-वोट भी नहीं दे कि एक? :)


संपादित करें - आप ज़्यादा व्यापक रास्ते में कैशिंग प्रदर्शन करने की जरूरत है, तो आप RazorEngineTemplateService और ITemplateResolver का उपयोग कर एक अलग दृष्टिकोण का उपयोग करना होगा।

स्टार्टर कोड का एक टुकड़ा यहां है;

public static RazorEngineTemplateService CreateService(ITemplateResolver resolver, ICollection<string> namespaces) 
    { 
     Check.IsNotNull(resolver, "resolver"); 
     var config = new TemplateServiceConfiguration(); 
     config.BaseTemplateType = typeof(PlainTextTemplate<>); 
     config.EncodedStringFactory = new RazorEngine.Text.RawStringFactory(); 
     config.Resolver = resolver; 
     config.Namespaces = new HashSet<string>(namespaces); 

     var service = new RazorEngineTemplateService(config); 
     return service; 
    } 

ITemplateResolver,, टेम्पलेट सामग्री में टेम्पलेट नाम देता है ताकि आप, लागू कर सकते हैं जैसे एक CachedFileTemplateResolver जो डिस्क से कैश की गई सामग्री लोड करता है।

+0

ऐप को पुनरारंभ किए बिना कैश को मैं कैसे अमान्य कर दूंगा? –

+1

यह समाधान आपके लिए यह नहीं करेगा, मुझे डर है। मुझे इसके लिए अपनी छोटी सी प्रणाली बनाना पड़ा जो टेम्पलेट सामग्री प्राप्त करने के लिए RazorEngine.Templating.ITemplateResolver क्लास का उपयोग करता है। मैंने आपके उत्तर के निचले हिस्से में कुछ स्टार्टर कोड जोड़ दिए हैं, यदि यह आपको सही रास्ते पर मदद करता है। –

+0

तो क्या आपको मूल रूप से कैश को अमान्य करने और फ्लाई पर पुन: संकलित करने के लिए डिस्क पर टेम्पलेट्स पर फ़ाइलवाटर डालने की आवश्यकता है? क्या पहले से ही कुछ बनाया गया है, या क्या मुझे इसे खुद रोल करने की ज़रूरत है? – crush

संबंधित मुद्दे