Evaluating an If Statement with Dynamic LINQ

In my previous post I described the basics for a new ASP.NET MVC View Engine that I’ve started working on, based on the popular Smarty PHP View Engine.

Here are my current goals for this project:

  1. Implement all the built-in functions from Smarty
  2. Use the new Microsoft Extensibility Framework to allow the View Engine to be extended
  3. Create a detailed example application using the new View Engine

I have started on all 3 goals but I’m trying to be more focused and finish them one by one.

Implementing an If statement

I have implemented quite a few of the built-in Smarty functions.  I went about in quite an ad-hoc way – I simply started implementing functions which I could easily understand while covering a broad range to help me figure out what I need to supply to functions and what they need to return.

The one function that I simply skipped was the If function.  I quickly realized that implementing this function would be very tricky.  The way that Smarty performs the evaluation of If statements (and pretty much all functions) is to translate the template to PHP – because PHP is a scripting language this solves your problem.  The compiled nature of C# makes this a very tricky exercise.  (Keep in mind that I’m not translating the template to C# code – I’m actually evaluating the template directly)

Dynamically Evaluating an Expression in C#

Let’s take a look at a typical If statement in Smarty.

{if $person.Name eq 'Fred'}
    <p>Hello Fred!</p>
{elseif $person.Age > 25}
    <p>You're old, {$person.Name}</p>
{/if}

As far as I know we have 2 solutions to this problem in C# 3.5 (the new dynamic stuff that will be introduced with C# 4.0 would hopefully solve this in a very elegant fashion). 

This first option is to generate the code for a class that evaluates the given expression, compile it and invoke the compiled code.  The closest I could find to this was a C# REPL solution.  My main concern with this approach is performance – evaluating the templates needs to happen as quickly as possible.  Any View Engine with poor performance is not going to be used by anyone – no matter how great the features are.

The second option is to use Dynamic LINQ.

Dynamic LINQ

A quick google on Dynamic LINQ will probably lead you to this post by Scott Gu.  I had a look at the Dynamic Query Library introduced there and it is exactly what I’m looking for.  The documentation included with the library is also excellent.

Here is one of the Unit Tests I wrote to get to grips with 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);
}

I also quickly realized that I could use this same mechanism for evaluating single expressions, for example:

<li>{$person.Details.Age}</li>

Previously I was manually evaluating the expression using some tricky reflection – Dynamic LINQ makes this a straightforward exercise.  You simply need to pass in null as the ResultType of the lambda expression.

Conclusion

I was pleasantly surprised by how easy it is to use Dynamic LINQ.  I had originally thought that evaluating expressions would either require an extensive amount of work or that I would need to place severe limitations on what you could do inside expressions.  Dynamic LINQ (and especially the Dynamic LINQ Library) makes this very simple.

I have included the Unit Tests I used for evaluating the Dynamic LINQ Library here.

Tags: C#