How are templates in RazorEngine cached?

前端 未结 2 723
不思量自难忘°
不思量自难忘° 2021-02-13 20:20

When you call RazorEngine.Razor.Compile(), where is the compiled template stored?

Is it available after the programs been restarted? If there is a memory sh

相关标签:
2条回答
  • 2021-02-13 20:32

    Currently, after the RazorEngine compiles the templates, they are loaded into memory. These assemblies persist in memory only and do not continue beyond the lifetime of the application.

    I am considering adding in support for compiling these assemblies to files, but that'll be a future version.

    If you call Razor.Parse and pass in a name for the template, it will attempt to

    1. Check the cache of in-memory assemblies for an assembly with the same name.
    2. Invalid the cache of the content of the template has changed.
    3. Cache the newly compiled template.
    0 讨论(0)
  • 2021-02-13 20:51

    I've got this to work with RazorEngine 3.4.1.0, installed late Jan 2014.

    The key is to call the expensive Razor.Compile(content, name) to put the template into cache, then call the cheap Razor.Run(name, model) to execute the template.

    Remember that reading template content might be expensive -- say, involving a read from disk -- so my solution only gets template content once. This might be too much caching for you, so careful!

    Here's the RenderPartial method I use inside a custom TemplateBase<T> subclass. It runs very quickly for multiple calls to the same template.

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

    You also need to tell Razor to use this base class (SqlTempalte<T>) which you can do like this, by calling RazorEngineConfigurator.Configure();

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

    Couldn't have done it without this SO answer -- why not give that one an up-vote, too? :)


    Edit - If you need to perform caching in a more granular way, you'll need to use a different approach using RazorEngineTemplateService and ITemplateResolver.

    Here's a piece of starter code;

        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 turns template names into template contents, so you can implement, eg, a CachedFileTemplateResolver which loads cached content from disk.

    0 讨论(0)
提交回复
热议问题