Шаблонирование с использованием нового API RazorEngine

Некоторое время назад рендеринг шаблона с использованием RazorEngine было так же просто, как:

string s = RazorEngine.Razor.Parse()

Однако по какой-то причине его авторы изменили свое мнение об API, и теперь самый простой способ визуализации шаблона:

var key = new RazorEngine.Templating.NameOnlyTemplateKey("EmailTemplate", RazorEngine.Templating.ResolveType.Global, null);
RazorEngine.Engine.Razor.AddTemplate(key, new RazorEngine.Templating.LoadedTemplateSource("Ala ma kota"));
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
RazorEngine.Engine.Razor.RunCompile(key, sw);
string s = sb.ToString();

(По крайней мере, это то, что я вывел из нового API. Старый помечен как устаревший.) Есть ли способ использовать новый API для рендеринга шаблона без кеширования, ключей и прочего? Все официальные примеры просто не работают.

4 ответа

Решение

После поиска кода я нашел несколько полезных примеров ( https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Hosts.Console/Program.cs) и обнаружил, что если вы включите

using RazorEngine.Templating;

В верхней части вашего класса вы можете использовать некоторые методы расширения ( https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Templating/RazorEngineServiceExtensions.cs), которые помогут вам.

Безболезненная подборка шаблонов:

Engine.Razor.Compile(templatePath, "templateNameInTheCache", modelType);

Разбор шаблона:

Engine.Razor.Run("templateNameInTheCache", modelType, model);

И теперь вы можете сделать оба одновременно!

string myParsedTemplate = Engine.Razor.RunCompile(templatePath, "templateNameInTheCache", null, model)

Что эквивалентно делать это

Engine.Razor.AddTemplate("templateNameInTheCache", TemplateLoader.GetTemplate(templatePath));
Engine.Razor.Compile("templateNameInTheCache", modelType);
string finallyThisIsMyParsedTemplate = Engine.Razor.Run("templateNameInTheCache", modelType);

Обратите внимание, что в настоящее время я тестирую это, но, похоже, работает нормально.

Следующий код работает для ResolvePathTemplateManager (Октябрь 2017 г.):

var templateManager = new ResolvePathTemplateManager(new[] { rootPath });

var config = new TemplateServiceConfiguration
{
    TemplateManager = templateManager
};

Engine.Razor = RazorEngineService.Create(config);

// ...

var html = Engine.Razor.RunCompile("Test.cshtml", null, model);

Источник: в RazorEngineServiceTestFixture.cs, ищите ResolvePathTemplateManager,

К вашему сведению, использование RazorEngine API приводит к утечке памяти. Сообщается об официальной проблеме, заключающейся в том, что при компиляции шаблонов постоянно создаются временные файлы, от которых очень трудно избавиться. Так что будьте очень осторожны, если используете это в продакшене.

В последний раз, когда я использовал это, он продолжал добавлять +1 МБ к памяти при каждой компиляции шаблона, даже при использовании кешированных шаблонов!

Основываясь на ответе @turdus-merula, я хотел, чтобы временные файлы были очищены при выгрузке AppDomain по умолчанию. Я отключил временную блокировку файла в конфиге, что позволяет удалять временную папку.

var config = new TemplateServiceConfiguration
{
    TemplateManager = new ResolvePathTemplateManager(new[] {"EmailTemplates"}),
    DisableTempFileLocking = true
};

Engine.Razor = RazorEngineService.Create(config);

var html = Engine.Razor.RunCompile("Test.cshtml", null, model);
Другие вопросы по тегам