RazorEngine un-cache compiled templates

后端 未结 3 1296
萌比男神i
萌比男神i 2021-02-07 15:02

Currently, I am using RazorEngine v2.1 as part of a background process that sends templated emails (thousands of them). To speed things up, the templates are compiled with their

3条回答
  •  太阳男子
    2021-02-07 15:18

    I recently upgraded to the latest stable version of RazorEngine (3.6.1) and my strategy for purging the cache no longer worked due to all the changes. A lot has changed and the documentation for this project is not only out of date but written from an authors perspective making for a poor user experience.

    This is my current code for purging all cached templates using the 3.6.1.

    public static class TemplateManager
    {
        static IRazorEngineService Service { get; set; }
        static TemplateServiceConfiguration Configuration { get; set; }
    
        static TemplateManager()
        {
            Configuration = new TemplateServiceConfiguration()
            {
                // setting up our custom template manager so we map files on demand
                TemplateManager = new MyTemplateManager()
            };
            Service = RazorEngineService.Create(Configuration);
            Engine.Razor = Service;
        }
    
        /// 
        /// Resets the cache.
        /// 
        public static void ResetCache()
        {
            Configuration.CachingProvider = new RazorEngine.Templating.DefaultCachingProvider();
        }
    
        /// 
        /// Compiles, caches and parses a template using RazorEngine.
        /// 
        /// Type of the template.
        /// Type of the anonymous object.
        /// true to enabled caching; false otherwise
        /// 
        public static string GetTemplate(EmailTemplateType templateType, T anonymousType, bool cachedEnabled = true)
        {
            string templateName = templateType.ToString();
    
            if (cachedEnabled == false)
                ResetCache();
    
            // pre-compile, cache & parse the template
            return Engine.Razor.RunCompile(templateName, null, anonymousType);
        }
    }
    
    public enum EmailTemplateType
    {
        ForgotPassword,
        EmailVerification
    }
    
    public class MyTemplateManager : ITemplateManager
    {
        public ITemplateSource Resolve(ITemplateKey key)
        {
            string file = HttpContext.Current.Server.MapPath(string.Format("~/EmailTemplates/{0}.cshtml", key.Name));
            return new LoadedTemplateSource(System.IO.File.ReadAllText(file), file);
        }
    
        public ITemplateKey GetKey(string name, ResolveType resolveType, ITemplateKey context)
        {
            return new NameOnlyTemplateKey(name, resolveType, context);
        }
    
        public void AddDynamic(ITemplateKey key, ITemplateSource source)
        {
            throw new NotImplementedException("dynamic templates are not supported!");
        }
    }
    

    This is an example usage of the code in Asp.Net MVC:

    var emailBody = TemplateManager.GetTemplate(EmailTemplateType.ForgotPassword, new
    {
        SiteUrl = Url.Action(MVC.Home.Index(), protocol: Request.Url.Scheme),
        SiteFriendlyName = SiteSettings.Instance.DomainName.FriendlyName,
        PasswordResetLink = Url.Action(MVC.Account.ActionNames.ResetPassword, MVC.Account.Name, new { userId = user.Id, code = code }, protocol: Request.Url.Scheme),
        NotRequestedUrl = Url.Action(MVC.Account.ActionNames.PasswordResetNotReqeuested, MVC.Account.Name, new { userId = user.Id, requesterIpAddress = WebUtils.GetClientIPAddress(), code = code }, protocol: Request.Url.Scheme)
    },
    /* this setting allows me to disable caching during development */
    !SiteSettings.Instance.EmailSettings.DebugEmailTemplates );
    
    // I could also have a button on an admin page that executed this code to manually reset the cache in production.
    TemplateManager.ResetCache();
    

提交回复
热议问题