I have been contacted a couple of times in the last month by developers having problems with lambda expressions with GlassHtml. In this short blog post we will explore how to correctly write lambda expressions and why.

Expressions

GlassHtml makes use of lambda expressions to describe which property should be made editable or rendered at run time. A simple example is:

    @Html.Glass().Editable(Model, x => x.Title)

In the Experience Editor this will create an editable field and in normal mode it will output the value in the Title field.

It is important to realise that there are two parts to this lambda expression:

1. The target object, called Model in this example but could be any variable name.
2. The expression, which is made up of the body (x.Title) and the lambda parameter (x).

When the lambda expression is executed, the target object is passed into the lambda expression. We can imagine this as a function call:

Func<MyModel> editTitle => (x) => x.Title;

editTitle(Model);

Lambda expression can be as complicated as you need them to be, but you must always use the lambda parameter in the expression body:

    @Html.Glass().Editable(Model, x => x.Children.First().Colour.Name)

Doing It Wrong

Lambda expressions where the lambda body references the target object (or another instance of an object) will have problems.

For example the following expression is wrong because the expression body references the target object.

      @Html.Glass().Editable(Model, x => Model.Title)

This second example is wrong because it references a another object in the expression:

     @{var childName = Model.SelectedName}
     @Html.Glass().Editable(page, x => x.Children.Where(y=>y.Name == childName).Colour.Name)

But why is this bad? See below.

Lambda Cache

Lambda expressions are not compiled into executable code when you build your application. Instead they must be compiled at runtime before they can be executed.

Compiling a lambda expression is not a trival task and if you have a lot of them can cause a performance issue. To resolve this, Glass.Mapper.Sc uses a lambda cache. Once a lambda expression has been compiled it is cached for the life of the application. This means a lambda expression is only compiled once by your application.

If you have written you lambda expressions correctly then this never causes you any problems.

If, however, you haven't, then you will start to seem some strange behaviour.

Lets imagine for the moment that we incorrectly wrote the following lambda expression:

      @Html.Glass().Editable(Model, x => Model.Title)

The first time this lambda expression is compiled and executed, a reference to the current instance of Model will be compiled and cached. What does this mean?

Well if your title property or Model contains the value "Sitecore Rocks", then on every page which this lamdba expression the value "Sitecore Rocks" will be returned. This will happen regardless of the value in Model because the first instance passed into the lambda expression was cached. All other Model values passed in are ignored.

Luckily solving the problem is simple!

Simple update the expression to use the lamdba parameter:

      @Html.Glass().Editable(Model, x => x.Title)

Disabling the Lambda Cache

Some developers have found a configuration property called UseGlassHtmlLambdaCache, by default this is set to true. DO NOT CHANGE THIS VALUE!! If you set this to false you may cause performance issues on your solution. This flag is only here for our internal testing. If you have problems which you think are related to the lambda cache then check you lambda expressions are correctly formatted.

- Mike

Glass needs your support!

Glass.Mappper.Sc is supported by the generous donations of the Glass.Mapper.Sc community! Their donations help fund the time, effort and hosting for the project.

These supporters are AMAZING and a huge thank you to all of you. You can find our list of supporters on the Rockstars page.

If you use Glass.Mapper.Sc and find it useful please consider supporting the project. Not only will you help the project but you could also get a discount on the Glass.Mapper.Sc training and join the Rockstars page.

Become a Rockstar