.NET Framework and CLR
We know that Visual Studio 2012 ships with and installs the new .NET Framework 4.5, which comes with new features such as portable class libraries, async/await support, async file I/O, and enhancements to W*F to name a few. This time, instead of installing the .NET framework side-by-side with previous versions, this one REPLACES the previous one (.NET 4). What does this mean?
.NET 2.0, 3.0, and 3.5 ran on top of the .NET CLR 2.0. Then .NET came along with its own .NET 4 CLR, but it installed “next to” the 2.0 CLR. If you run a .NET application targeted at 2.0 through 3.5, your app would be using the .NET 2.0 CLR. If you run a 4.0 application, it would use the 4.0 CLR. Now .NET 4.5 comes along, and you would think it would either (a) run against the existing 4.0 CLR, or (b) come with it’s own CLR. Well, it does neither – it REPLACES the 4.0 CLR with its own, the 4.5 CLR. Clear as mud? Here’s a good picture from Microsoft that describes the landscape.
What gets difficult is identifying what version of the .NET framework you have installed on your machine, either by hand or programmatically at runtime. Since the 4.5 CLR replaces the previous one, it lives in the same exact place on disk – most of it at %WINDIR%\Microsoft.NET\Framework\v4.0.30319. This version-based name of the folder did not change between 4.0 and 4.5. What DID change are the files contained in the folder.
|.NET 4.0 Installed||.NET 4.5 Installed|
|Target .NET 4.0||Target .NET 4.5|
Notice the Environment.Version property returns the same thing whether you’re targeting 4.0 or 4.5 framework in your project. This is because this property returns the CLR version (remember 4.0.30319.17929 means 4.5), not the version of the framework you’re code is targeted to.
You might be asking, “how do I know what’s installed on this machine?”. In the past, I’ve gotten used to opening the %WINDIR%\Microsoft.NET\Framework directory structure and checking the folder names, but that’s not enough with 4.5. There are 3 ways that I know of:
- Check the FILE VERSION of one of the .NET framework assemblies (MSCOREI.DLL, SYSTEM.DLL, etc)
- Check the Programs and Features list for “Microsoft .NET Framework 4.5”. To complicate matters, it shows a version of 4.5.50709.
- Check a gnarly registry key: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full. If there’s a DWORD value named “Release”, then you have .NET 4.5. If it’s greater or equal to 378389, then you have the final released version of .NET 4.5.
You can run .NET 4.0 code on a machine with .NET 4.5 installed, that’s just standard backwards compatibility. But can you run .NET 4.5 code on a machine with .NET 4.0? Since the CLRs are “pretty similar”, only with 4.5 having more features, the 4.0 code will actually run, but only if you don’t use any 4.5 specific features that are not present in the 4.5 CLR. For example, if you use the new 4.5 async/await pattern in your code, it will blow up on a machine with only 4.0 installed.
I mention EF here not because it comes with Visual Studio 2012 (it’s available via NuGet), but because it has some interesting version behavior as well. EF 5 comes with support for Enum types, which means your database tables will have first hand knowledge of the Enum values, instead of forcing you to use strings and lookup tables. However, that support for Enum is built upon new functionality in the .NET 4.5 framework. So if your project is targeting .NET 4, you don’t have Enum support. What’s tricky about this is the way NuGet sets up the references to Entity Framework for you. It’s smart about it, but it’s not obvious.
When you use NuGet to add EF support to your project, the installation process detects what .NET version your project is targeting. If it’s 4.0, your project will reference the 4.4 version of EF, the one WITHOUT support for Enums. If your project is targeting .NET 4.5, your project will reference the 5.0 version of EF, and WILL have support for Enums. You can see which one you have based on the version number of the EntityFramework referenced assembly.
|Targeting .NET 4.0||Targeting .NET 4.5|
Well that’s enough version information for one post. Hopefully this gives you a hint as to what is going on in your application when you’re running on machines with different versions of the .NET Framework.