Razor Templating Engine vNext

Where are we?
We’ve just released v1.2 of our Razor Templating Engine (razorengine) project on CodePlex (http://razorengine.codeplex.com) and as always we’re looking at ways we can improve it. There are a couple of things we are addressing, and will look to be doing in the future.

The v1.2 release brought about corrected support for Unit testing scenarios, although it was an ugly hack. Essentially the Microsoft.CSharp library (although referenced) wasn’t referenced in the final code as no types were used by the library, this leads to the compiler omitting the reference from the outputted assemblies metadata. Not sure if there is a better way to do it, if you know, let us know!

v1.2 also brought updated support for pre-compilation of templates, whereby you could:

string template = “Hello @Model.Name”;
Razor.Compile(template, “myTemplate”);

string result = Razor.Run(“myTemplate”, new Model { Name = “World” });
We had to splinter the Compile method into two separate methods, Compile and CompileWithAnonymous, the second is required as we can’t safely determine whether the pre-compiled template is using an anonymous class without actually passing in an instance of it. At the Compile stage, the instance is completely redundant, so we’ve now got two methods. Luckily the related Run method is more simplistic and doesn’t have a seperate XWithAnonymous counterpart.

We pushed out all these changes to the TemplateService type, as in doing so brings per-instance pre-compilation support to the TemplateService, which may be configured to create different types of templates.

What’s next?
There are some quite major changes which will need to take place, namely around the ASP.NET Medium trust issue which still plagues our little framework, the other is any architectural changes which the RTM’d version of Razor may bring.

Razor RTM Support
The library on codeplex is still using the Beta library of Razor, and I believe there are already changes to do with the Razor host in the RC. Without doing a full audit of what changes have occured, we can’t safely determine at this stage how this is going to affect the framework. Naturally we want to provide the most updated Razor library to give support for all the features the Microsoft team are building into Razor.

ASP.NET Medium Trust Issue, ala the bane of my existence [BOME]
Let’s have a quick overview of the Medium trust issue. The Razor parser essentially works in two parts, a code parser and a markup parser. The two together generate the Execute method within the template which, once compiled means we can execute templates quickly (straight code execution, no template interpretation). The code generator used is of a type that inherits from a CodeDomProvider, such as the CSharpCodeProvider. On both of these types we have LinkDemand and InheritDemand permission attributes which enforce that calling code and inheriting code must be running in Full Trust. How does this work in Medium trust environments I hear you ask? ASP.NET relies on the BuildProvider model which is GAC’d and implicitly given the appropriate permissions to generate code for compilation (code typically derived from .aspx files is an example).

So where do we stand? We need to target scenarios where Medium trust is enforced and our library isn’t GAC’d. In other words, we need to target most shared hosting scenarios. This means the only likely solution for us in this scenario is to create a new BuildProvider and defer compilation to the ASP.NET build system. This is a little tricker than it sounds as the BuildProvider model requires a virtual path, so on top of implementing a BuildProvider we then either have to dump the string templates out to the file system, or we also have to implement a VirtualPathProvider. This is a lot of work to fix the Medium trust issue. On top of that it may require other changes to the core library to support this new compilation model. I don’t want to introduce a dependency on System.Web in the core library either, as this means dropping support for Client Profile too. Looks like we may have to abstract the RazorCompiler more to support an interfaced approach to compilation providers?

My first question on Stack Overflow (Compiling Code in Medium Trust) is still open and although the suggestions of using an alternative compiler are good, they wouldn’t work as we are not in control of the code generation, that is up to Microsoft’s Razor library. I’ll keep this question open just in case some one comes up with any gems!

Custom Namespaces and Configuration
One of the glaringly missing features in the current v1.2 release (and priors) is that we didn’t give an easy way of adding in custom namespaces to allow you to use other types, such as String.Format(…). In Changeset 5659 (here) we’ve enhanced the framework to support configuration. With configuration we can now:

<templateServices default="myDefaultTemplateService"> <add name="myDefaultTemplateService" languageProvider="RazorEngine.Compilation.CSharpLanguageProvider, RazorEngine.Core"> <namespaces> <add namespace="System.IO" /> </namespaces> </add> </templateServices>
Code language: HTML, XML (xml)

It’s a bit verbose but it gets the job done. This might need to be tweaked for a bit but this also now gives a configuration mechanism to build on if we need to. To access configured instances of TemplateService, you can now use the Razor.Services[“name”] dictionary. The default template service becomes the service used directly by the Razor static class.

User Feedback
As always we want to continue getting feedback from the community of users currently developing with the Razor Templating Engine, how are you using it? What issues are stopping you from using it? Where would you like us to go next?

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Post