Your official information source from the .NET Web Development and Tools group at Microsoft.
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?
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:
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.
Enabling the new Roslyn compilers in your ASP.NET application will result in two main benefits:
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.
To properly enable Roslyn compilation in ASP.NET you need to do two things:
The first item will cover the project compilation portion of your ASP.NET application. The second item will cover the runtime compilation portion.
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.
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!
Very nice! Tried it on our solution and it is loading much faster. It seems like I still have to compile whenever I make a change to the code behind of a control. Should I be able to make a change to any code and just refresh the site to see the modified behavior or I need to compile it first?
@Etienne - This won't add any new features like that. It's simply a replacement for the ASP.NET runtime compiler that uses Roslyn for the compilation step. Glad you like it!
I'm not sure if this is the same thing, but I added Microsoft.CodeAnalysis.Common and Microsoft.CodeAnalysis.CSharp through nuGet to my ASP.NET application but I get a runtime exception: "The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=126.96.36.199, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'."
@Jeric That's a different thing. This is a known issue with the System.Collections.Immutable.dll, which is used by the NuGet package you installed and has dependency on System.Runtime.dll. Adding the config section below in your web.config should resolve your problem,
<add assembly="System.Runtime, Version=188.8.131.52, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
this is fantastic - million $ question - any hints on timeline for being able to use in production?
@taylor nothing more specific than sometime next year
Would it be possible to add some kind of event that an application could subscribe to to know when a compile kicks off? This is mainly so that we can log when these things occur.
When fully compiled web application deployed then also roslyn help ?
Roslyn also help in case of fully compiled web application
Works great. Though hasn't been updated for a long time and not compatible with the latest version of the Roslyn compiler.
Another issue, this release doesn't seem to support conditional compilation symbols defined in configuration
@Dmitry There is new version available on nuget.org. You may want to have a try.
I have tried the latest version of the NuGet package, but there's seem to be a difference in the way the compiler is loaded/executed
In the v0.2.0.0 the Roslyn compiler would be loaded into memory, improving greatly performance for not pre-compiled websites with multiple *.as*x/*.cshtml files. The new version, however, features a new /bin/roslyn/csc.exe file, which is executed once per file, completely removing the mentioned above optimization feature.
Is it possible to configure Roslyn to execute it in a mode similar to the way it was working previously (either loaded into memory or may be reusing the same csc.exe instance for multiple compilations) ?.
And - will the feature also be removed in the final release?
@Dmitry The job of the csc.exe in /bin/Roslyn is to invoke the VBCSCompiler.exe, which sits in the same folder. VBCSCompiler.exe is the process that does the actual compilation work. If the VBCSCompiler is already running csc.exe will reuse it and thus we will still gain the mentioned performance improvement.
@Dmitry The job of the csc.exe in the \bin\Roslyn is to invoke the VBCSCompiler.exe, which sits in the same folder, and pass the compilation parameters to the later process. The VBCSCompiler.exe is the one that does the actual compilation work. If a VBCSCompiler.exe is already running, the csc.exe will reuse the instance and thus we will still gain the mentioned performance improvement.
Hi @XMao, that might have been the intention.
But practically - when I try it on a website with a lot of *.ascx/*.aspx C# files, where all the controls are loaded in a loop in a background thread with System.Web.Compilation.BuildManager.GetCompiledType(virtualPath), which we do to improve user experience, so they don't have to wait much for the compilation after clicking on a new page with lots of not yet loaded controls.
I can see that for every compilation there's a new instance of csc.exe created an deleted shortly after for every compilation.
It eats up to ~90MB memory and high CPU usage for a short time - so it must be doing all the compilation work.
In my cases the total execution time for the loop is 60-80 seconds on the 184.108.40.206 version, when on 0.2.0.0 it is much faster, about 12-15 seconds.
I checked - and it is the csc.exe file from the /bin/roslyn folder, and not the default one.