Tengo que esto funcione con RazorEngine 3.4.1.0, instalado a finales de enero de 2014.
La clave es llamar a la cara Razor.Compile(content, name)
para poner la plantilla en caché, a continuación, llamar a la Razor.Run(name, model)
barato para ejecutar la plantilla.
Recuerde que el contenido de la plantilla de lectura puede ser costoso, por ejemplo, que implica una lectura del disco, por lo que mi solución solo obtiene el contenido de la plantilla una vez. Esto podría ser demasiado almacenando en caché, ¡así que cuidado!
Aquí está el método RenderPartial
que uso dentro de una subclase personalizada TemplateBase<T>
. Se ejecuta muy rápido para múltiples llamadas a la misma plantilla.
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
}
}
también hay que decir la maquinilla de afeitar para usar esta base de clase (SqlTempalte<T>)
que se puede hacer como esto, llamando 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;
}
}
No podría haber hecho sin this SO answer - por qué no dar que uno un up-voto, también? :)
Editar - Si usted necesita para llevar a cabo el almacenamiento en caché de una manera más granular, tendrá que utilizar un enfoque diferente utilizando RazorEngineTemplateService
y ITemplateResolver
.
Aquí hay un fragmento de código de inicio;
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
convierte nombres de plantilla en contenido de la plantilla, por lo que puede poner en práctica, por ejemplo, un CachedFileTemplateResolver
que carga contenido almacenado en caché de disco.
Muchas gracias por responder mi pregunta. No sé por qué nunca vi esto. Entonces, si y solo si paso un nombre a Razor.Parse y la plantilla es idéntica a la vez anterior llamé a Razor.Parse con el mismo nombre. ¿Entonces usará el ensamblado en caché en lugar de crear uno nuevo? – Rabbi
@Rabbi Sí, así es como funciona. Al pasar un nombre de la plantilla, tomamos el código hash del contenido de la plantilla y lo almacenamos en la memoria caché junto con el tipo compilado dinámicamente. La próxima vez que lo llame, si el código hash de la cadena de la plantilla no ha cambiado, podemos instanciar libremente el tipo de plantilla y ejecutarlo. De lo contrario, invalidamos el tipo existente en la caché y volvemos a compilar la base en el nuevo contenido de la plantilla. –
FYI, así no es como funciona en el RazorEngine actual. Profilling mostró Razor.Parse causando retrasos de 2 segundos en cada llamada web. Desactivándolo con Razor.GetTemplate(); Razor.Run(); correctamente desencadenado el almacenamiento en caché para nosotros. – KallDrexx