Sunday 24 January 2016

.NET 4.6 and Roslyn

When comparing .NET and Java there used to be a small difference that I considered as an advantage on the .NET side. The JRE does not come with the Java compiler, so even for writing a helloWorld program you'll need to install the JDK. On the other side, the .NET framework used to be installed with the csc and vbc compilers (they are in C:\Windows\Microsoft.NET\Framework64\v4.0.30319 along with the framework assemblies), so you can open a text editor and start to code.

This has changed a bit with .NET 4.6. You still will find a C# compiler in the framework folder, but the crazy thing is that that is not the new, C# 6, Roslyn based compiler. If you run it you'll see this message:

So where is the brand new cool compiler? The shocking answer is, nowhere, the so important Roslyn, on which Microsoft spent like 5 or more years is not part of the Framework, you'll have to install it separately. It'll get installed by Visual Studio 2015 (Community version also, of course) here: %ProgramFiles(x86)%\MSBuild\14.0\bin, but if you don't want to go through the lengthy installation (I've never understood why Visual Studio is such a monster, it takes much longer to install that installing a full OS like Ubuntu, while installing SharpDevelop takes like 2 minutes) you can just install the nuget package (it's mentioned here). By the way, Roslyn is now named The .NET Compiler Platform. Notice that you don't need Visual Studio to install nuget packages, hopefully you can just get the command-line utility (nuget.exe binary) from here.

So, why would Microsoft decide to keep the new compilers away from the framework? I assume they want to keep the standard Framework slim (apart from the "ultra slim" .NET core). Then, why didn't they also remove the old compilers? Well, the reason why the comilers have been a part of the runtime since its early beginnings is because one part of the base library makes use of them, CodeDom. When you use the CodeDom to create code at runtime, it ends up calling the (classic) csc compiler executable (sure it's strange, even when the old compiler is native code, not managed code, I would say that the normal approach would be to have its logic in a dll and have CodeDom call it via PInvoke). Notice that the 2 main view engines for ASP.NET, Razor and aspx, both use CodeDom to compile the views, so removing the compiler from the runtime would break the CodeDom, breaking pretty important existing code (imagine that if after installing .NET 4.6 on a Server all the Web Apps installed there would stop working!!!

So I guess Microsoft kept the old compilers to avoid breaking code but did not include the new ones (which would involve all the Rosly assemblies) to prevent the runtime from getting fatter. The old consequence is that if you add C# 6 features in your views, they will fail to compile at runtime unless that you specify that you are using an updated version of the CodeDom that uses Roslyn rather than the old compilers, CodeDom Providers for .NET Compiler Platform. It is explained here. The astonishing thing is that when passing these assemblies through ILSpy, they do not seem to reference the Roslyn assemblies (Microsoft.CodeAnalysis.dll and so on):

So I would say they are calling running the (new) compiler .exe. Roslyn offers to us a managed API acting as a compiler as a service, so why the hell these new CodeDom providers would need to run the binaries???
Honestly, I have no idea.

No comments:

Post a Comment