Enabling the .NET Compiler Platform (“Roslyn”) in ASP.NET applications
The .NET languages team recently announced the availability and open sourcing of a public preview of “Roslyn”, the new .NET Compiler Platform. This is the long awaited .NET “compiler as a service” that represents the future of languages and compilation for .NET. You can download a preview including new compilers and Visual Studio tooling that enable you to explore upcoming features in the languages and Visual Studio editor, but how do you use these new features in an ASP.NET application?
Compilation in ASP.NET applications
First, let’s take a moment to revisit compilation in the context of ASP.NET applications. There are generally two types of compilation that typically take place in an ASP.NET application: project compilation, and runtime compilation.
This type of compilation is used by ASP.NET applications built using the project system approach, i.e. they have a .csproj/.vbproj file. Project compilation typically takes place in Visual Studio via the project system and msbuild. It compiles any C# or VB files in your project and produces an assembly in the project’s bin folder. This assembly is then deployed to your web server along with your application and is loaded by the ASP.NET runtime when your application starts. Note this assembly could also be built from the command line using msbuild directly, e.g. when on a continuous integration or build server.
Assets such as page, user control, and handler code-behind classes, controllers and embedded resources are built using project compilation. Typically the source code for these assets is not deployed to the server. Other asset types, including .aspx, .ascx, .ashx, .cshtml, and .vbhtml, are deployed to the server and built by the ASP.NET runtime itself using runtime compilation.
ASP.NET includes a full runtime compilation pipeline that compiles many of your application’s assets on the web server when the application is running (hence “runtime compilation). Even if you’re using the project compilation model detailed above, part of your application will be compiled using ASP.NET’s runtime compilation feature. If you’re using the “Web Site” model for your application (you chose File –> New Web Site… in Visual Studio and your application doesn’t have a .csproj/.vbproj file) your application is built exclusively using ASP.NET’s compilation system. In this model, your application will contain shared code files in the App_Code folder.
Page assets in your application such as .aspx, .ascx and .cshtml/.vbhtml files, are compiled in the following fashion:
- The file is parsed and turned into CodeDOM using the configured build provider
- The CodeDOM graph that represents the file is used to generate a string of C# or VB code using the configured CodeDOM provider (the code generation step)
- The C# or VB code is then compiled into an assembly using the configured CodeDOM provider (the code compilation step)
- The assembly is loaded into the application and optionally cached to disk in the Temporary ASP.NET Files folder
You can read more about ASP.NET’s compilation system on MSDN.
To confuse matters slightly, you can elect to pre-compile the portions of your application that use the ASP.NET runtime compilation system before deployment, so that the compilation doesn’t take place at runtime. This is achieved using the ASP.NET Compilation Tool, aspnet_compiler.exe. This will produce assemblies that can be deployed along with your application in the bin folder and will remove the cost associated with compiling those assets when the application starts up. The tool is simply a wrapper around the runtime compilation feature and doesn’t use msbuild in any way. It will only compile the portions of your application that would’ve been compiled at runtime by ASP.NET, so if you’re using the project compilation model from above, you’ll still need to compile your application’s project using Visual Studio or msbuild.
You can read more about ASP.NET pre-compilation on MSDN.
Why Roslyn compilation in ASP.NET?
Enabling the new Roslyn compilers in your ASP.NET application will result in two main benefits:
- Support for new language features
- Potentially improved application startup/pre-compilation time
The first item is pretty self-explanatory. The second should be particularly helpful for customers with very large, complex ASP.NET applications. In our testing of a suitably large and complex application (>600 assemblies in bin, >500 user controls & pages), the runtime compilation cost at startup/pre-compilation dropped from ~15 minutes to ~70 seconds after enabling the new CodeDOM providers detailed below.
Enabling Roslyn compilation in ASP.NET
To properly enable Roslyn compilation in ASP.NET you need to do two things:
- Install the .NET Compiler Platform (“Roslyn”) End User Preview on your developer machine (where you use Visual Studio or build your application’s project file)
- Install the new CodeDOM Providers for .NET Compiler Platform (“Roslyn”) NuGet package into your ASP.NET application. In the Package Manager Console in Visual Studio type: install-package Microsoft.CodeDom.Providers.DotNetCompilerPlatform -pre
The first item will cover the project compilation portion of your ASP.NET application. The second item will cover the runtime compilation portion.
Announcing the first preview of new CodeDOM Providers for .NET Compiler Platform (“Roslyn”)
You can now get the first preview release of new CodeDOM providers that use Roslyn from NuGet in the Microsoft.CodeDom.Providers.DotNetCompilerPlatform package. Install the package into your application using NuGet in Visual Studio. These are a drop-in replacement for the in-box providers and installing the package is all you should have to do to enable them (the package will modify your web.config file for you). That said, if you want the best possible startup time, you can elect to Ngen and GAC the Roslyn assemblies so that your application doesn’t have to pay the cost of JIT’ing and loading them at runtime (which can be measurable given the size of the Roslyn assembly).
The new providers work equally well at runtime and when using the ASP.NET Pre-compilation tool, aspnet_compiler.exe. The tool will read your application’s web.config file and load the configured CodeDOM provider so you’ll get benefits regardless of whether you pre-compile your application or let ASP.NET do it on the web server.
The new providers only replace the compilation step of ASP.NET’s runtime compilation feature. Your .aspx, .cshtml, etc. files are still parsed and the C#/VB code is still generated using the same mechanisms as before, but the final compilation now takes place using Roslyn.
The providers are currently version 0.1.0-pre, so it should be obvious these are still very much in the pre-alpha stage. The internal implementation may change before we settle on a 1.0.0-beta but your application shouldn’t know any different. We’ll continue to release previews as the Roslyn team produce updates to the corresponding Roslyn NuGet packages. In the future, we’ll update the ASP.NET project templates in Visual Studio to use the final version of these providers by default.
We’re keen to have customers use them and provide feedback so we can make them the best they can be. We’ve tested the providers with a number of common ASP.NET application frameworks including DotNetNuke, Orchard, and Umbraco.
Known issues in the preview
- In this first preview, only C# is supported. VB support will be added in a future release
- Small applications may actually see an increase in application startup time. In our testing this was only a few seconds and in moderately sized applications this is more than overshadowed by the reduction in compilation of the application itself at startup
- Very large pages containing long spans of HTML with no server blocks (e.g. <%= %>) can cause a stack overflow when debug compilation is enabled that will crash the application. Note that in our testing it’s taken a page that’s ~4x as large one that would’ve produced a similar issue in the old provider, but in this case it crashes the entire application, whereas with the old provider it just fails the offending page
- If you retarget your app to 4.5.1 in Visual Studio after installing the NuGet package, the web.config changes are lost and will need to be reapplied manually
If you find any issues or want to ask a question regarding what’s discussed in this article, please leave a comment below, or use the Contact Owners form for the NuGet package.
We hope you enjoy using Roslyn in your ASP.NET applications!