В моем предыдущем посте я описал основы нового ASP.NET MVC View Engine, над которым я начал работать на основе популярного Smarty PHP View Engine.
Вот мои текущие цели для этого проекта:
- Реализовать все встроенные функции от Smarty
- Используйте новую Microsoft Extensibility Framework, чтобы позволить View Engine быть расширенным
- Создайте подробный пример приложения, используя новый View Engine
Я начал все 3 гола, но я стараюсь быть более сфокусированным и заканчиваю их один за другим.
Реализация оператора If
Я реализовал довольно много встроенных функций Smarty. Я ходил в довольно одноранговой образом — я просто приступил к реализации функций , которые я мог бы легко понять, покрывая широкий диапазон , чтобы помочь мне понять, что мне нужно поставить к функциям и что они должны вернуться.
Единственной функцией, которую я просто пропустил, была функция If . Я быстро понял, что реализовать эту функцию будет очень сложно. Способ, которым Smarty выполняет оценку операторов If (и почти всех функций), заключается в переводе шаблона в PHP — поскольку PHP — это язык сценариев, который решает вашу проблему. Скомпилированная природа C # делает это очень сложным упражнением. (Имейте в виду, что я не переводю шаблон в код C # — я на самом деле оцениваю шаблон напрямую)
Динамическая оценка выражения в C #
Давайте посмотрим на типичное утверждение If в Smarty.
{if $person.Name eq 'Fred'}
<p>Hello Fred!</p>
{elseif $person.Age > 25}
<p>You're old, {$person.Name}</p>
{/if}
Насколько я знаю, у нас есть два решения этой проблемы в C # 3.5 (новый динамический материал, который будет представлен в C # 4.0, надеюсь, решит это очень элегантным образом).
Этот первый вариант — создать код для класса, который оценивает данное выражение, скомпилировать его и вызвать скомпилированный код. Наиболее близким к этому я мог найти решение C # REPL . Мое основное беспокойство в связи с этим подходом — производительность — оценка шаблонов должна происходить как можно быстрее. Любой View Engine с низкой производительностью не будет использоваться никем — независимо от того, насколько хороши функции.
Второй вариант — использовать Dynamic LINQ.
Динамический LINQ
Быстрый Google на Dynamic LINQ, вероятно, приведет вас к этому сообщению Скотт Гу . Я посмотрел на динамическую библиотеку запросов, представленную там, и это именно то, что я ищу. Документация, включенная в библиотеку, также превосходна.
Вот один из модульных тестов, которые я написал, чтобы справиться с Dynamic LINQ.
[Test]
public void ShouldParseBooleanStatementWithParameters()
{
var x = Expression.Parameter(typeof(int), "x");
var expression = DynamicExpression.ParseLambda(new[] { x }, typeof(bool), "5 == x");
var compiled = expression.Compile();
var result = (bool)compiled.DynamicInvoke(5);
Assert.IsTrue(result);
}
Я также быстро понял, что могу использовать этот же механизм для вычисления отдельных выражений, например:
<li>{$person.Details.Age}</li>
Ранее я вручную вычислял выражение, используя некоторые хитрые размышления — Dynamic LINQ делает это простым упражнением. Вам просто нужно передать значение null как ResultType лямбда-выражения.
Заключение
Я был приятно удивлен тем, как легко использовать Dynamic LINQ. Первоначально я думал, что оценка выражений потребует большого объема работы или что я должен наложить серьезные ограничения на то, что вы можете делать внутри выражений. Dynamic LINQ (и особенно Dynamic LINQ Library) делает это очень простым.
Я включил модульные тесты, которые я использовал для оценки динамической библиотеки LINQ
Свежие комментарии