Monday, August 24, 2009

All for that small Drop Down Box – Part 1

Multi Targeting in Visual Studio 2010 is surprisingly a big feature area… It falls under the category of what we called as a “Divisional Initiatives” which spans across nearly all of Visual Studio and .NET Framework teams… Even engineers from outside of VS and .NET teams contributed significantly on the project... With this series of blog posts I am going to merely focus on MultiTargeting (MT) for Web Developers in Visual Studio 2010 and ASP.NET 4…

First of all let me call out by saying that in VS 2008 there was only one version of CLR i.e. CLR 2.0… Various framework versions i.e. .NET 2.0, .NET 3.0 and .NET 3.5 were only changes to the framework assemblies which still ran on the same CLR 2.0…  With .NET 4 this equation changes coz .NET 4 runs on CLR 4…  VS 2010 now needs to support .NET 2.0, .NET 3.0, .NET 3.5 as well as .NET 4 Applications; this implies that now we are about to cross into different CLRs for Applications targeting different Framework Versions… Solving this issue is in part what VS 2010 MT is all about… Solving this problem for various ASP.NET Web projects is what Web MT is all about…

As VS 2010 itself loads CLR 4, trying to create, edit, debug, deploy applications with VS 2010 running on CLR 2 would mean loading CLR 2 inside CLR 4…  That without going into detail is a technical nightmare… To overcome this VS 2010 loads only CLR 4 and .NET 4 in its process and for applications targeting .NET 2.0, 3.0 or 3.5 VS 2010 makes .NET 4 emulate .NET 2.0/3.0 or 3.5.

So how does the emulation inside VS 2010 really happen?

With VS 2010 there is a new concept called as “Reference Assemblies”… “Reference Assemblies” simply put are meta data assemblies which represent each framework… These assemblies do not contain the complete implementation of the framework they just allow VS 2010 to decipher what classes, methods, properties, resources etc are really present in each .NET Framework version… You can find these “Reference Assemblies” in %Program Files%\Reference Assemblies folder…. There is more to the process of creating “Reference Assemblies” and registering them etc but for now I will not get into those details…

As I mentioned earlier inside VS 2010 process only CLR 4 and .NET Framework 4 is loaded… If you create a .NET 2.0 project, VS 2010 will use the .NET 2.0 Reference assemblies to ensure that your project behaves like a .NET 2.0 app… Although, all the time when you are editing your .NET 2.0 code, designing your web pages, authoring controls, debugging etc you are actually using .NET 4 but VS 2010 is masking off all the .NET 4 features based on the directions provided by .NET 2.0 Reference Assemblies… Now when you build your projects VS 2010 cannot use .NET 4 and CLR 4 to create the output assemblies coz if VS 2010 would do that then you would not be able to run your project on a box which only has only .NET 2.0 (i.e. not CLR 4/.NET 4)…  Hence, when it comes to building the assemblies VS 2010 launches the correct compilers out of process and generates the correct assemblies for your project…

Now with this high level understanding let me mention that as I write this article I am thinking that I have been lucky to have worked with great engineers across the company to make the VS 2010 MT experience the way it is today and additionally I feel lucky that people whom we build all this stuff for (ie .NET developers world wide) can actually understand what goes into development of such a system as Visual Studio and .NET Framework… Anyways, let us get into the meat of what all does all this crazy MT stuff buys web developers at the end of the day (APART FROM THAT SMALL DROP DOWN BOX that you see…  :-)

small drop down box

Migrating pre-VS 2010 (starting from VS 2003) web projects to VS 2010 – One of the feature areas of Web MT is migration of apps created using previous version of VS to VS 2010.  VS 2010 allows migration from VS 2003, VS 2005 as well as VS 2008…  This entails modifying the solution files (.sln) and project files (.csproj/.vbproj) of your Web Projects to make them complaint with VS 2010 format.

Have you wondered why do we need to do that??  As you might already know project and build systems within VS work using MSBuild… There are target files and task dlls which are installed as part of VS 2010 in specific directories… These directories need to be side by side with VS 2008/VS 2005 directories to ensure that you can run VS 2008 and VS 2005 on the same box and uninstalling of any of the IDEs does not break the other versions… Anyways, there are references to various target files inside the solution and project which need to be updated to be point to the correct directories of VS 2010… Apart from that there is also changes to IDE version etc which is embedded inside these files which are used by VS, all that stuff needs to be updated…

When you open VS 2003/2005 or 2008 projects in VS 2010, VS will automatically do this migration for you.

People always bring up the discussion where they would like few developers in their team try out VS 2010 and remaining stay with VS 2003/2005 or 2008.  They typically want to try out the VS 2010 release in a limited way and once the few folks trying the product give a green light they would move the entire team to VS 2010…  Doing this is of course possible but an additional ask which comes with that is “Can we have some developers use VS 2010 while others use VS 2008 for the same project/solution file in a common source control?”; unfortunately the answer to that is No…  The process of having the same project being operable in various versions of VS is what we call as “Round-Tripping”… We really did want to include this feature for VS 2010 but unfortunately could not due to the existing complexity of MT (as discussed above, below and everywhere in this post :-)) + limited time to get everything right… !!  Well, what is important is that we will make everyone in your project team move to VS 2010 easy enough that you can have the entire team bet on it at the same time…!!  Let us see how -

Upgrading pre- .NET 4 web projects to .NET 4  - VS 2010 will also allow you to upgrade your .NET Framework version from .NET 2.0, 3.0 or 3.5 to .NET 4…  This now enters the realm of making changes which impact your code… That is the reason VS 2010 allows you to either stay with your existing Framework version or upgrade the Framework version to .NET 4… There are tons of cool new ASP.NET 4 features, I encourage you to read the whitepaper on ASP.NET 4 and VS 2010 to learn more… -

Creating .NET 2.0, 3.0, 3.5 as well as .NET 4 projects – This is drop down box  which I am referring to in the title of this article… :-)  It will manifest itself again but what is important to note is that when you try to use File –> New –> Project or File –> New –> Web Site (as shown below), you will get a choice to choose the Framework version of your choice for the new project…

new project framework dropdown

Some folks will still have their web servers set up only for .NET 3.5 and in that case they can choose the corresponding framework version from the drop down…  As soon as the framework version is chosen in you will notice that the project templates will get filtered correctly…  When any of the project templates (or item templates) are authored we now have a concept of embedding the “Min Framework Version” and “Max Framework Version” in them…  This allows VS 2010 to determine which templates to show and hide when you are choosing a particular Framework.  It also ensures that we do not need to have multiple copies of the same template within VS saving time and size during VS 2010 install…

Filtering Item Templates for Framework Version – Similar to the project templates discussion above are the details for the Item templates…  When you go ahead and try to right click on your project and Add—> New Item, similar filtering happens… For e.g. you do not see “ADO.NET Entity Data Model” item template if you right click on a .NET 2.0 project

image 

Item template filtering works similar to project template filtering… Also it is worth noting that there can always be custom code which can be run during “Project creation” or “adding Item Template” which allows VS 2010 to do special things with the template per .NET framework version…  A good example of this is the web.config file template which needs to generate different web.config file based on the .NET framework version…  So if you crack open a item template you might see some conditional framework based logic in there… :-)

ToolBox Filtering – As you are about to design your page or user control you may tend to drag and drop controls from toolbox… At this time VS 2010 needs to make sure that you see only the controls that your .NET version allows…  If you remember I mentioned earlier that VS 2010 is always running .NET 4…  If the toolbox showed all the controls associated with .NET 4 all the time then you might see unwanted controls when you are targeting .NET 2.0 and potentially may have errors in production if you used .NET 4 controls in .NET 2.0 projects… To avoid this from happening VS 2010 uses “Reference Assemblies” and the entire architecture surrounding them to identify what controls need to be shown in the toolbox…

At this time VS 2010 also gathers what the tooltip for the controls and shows them correctly to you so that you know what type of control are you using…

toolbox version tooltip

Additionally what is interesting to note is that the toolbox meta data population also happens for 3rd party controls and hence even if you were using Infragistics or Dundas control their metadata will also get correctly reflected in the Toolbox i.e. their framework dependency chain will be walked and correct Framework dependency will be verified…

As you can imagine there is a lot of work being done based on your framework version to go down to “Reference Assemblies” and find out what needs to be shown what does not and only after all that the toolbox gets populated correctly…

Property Grid Filtering – Now if you pause and ponder for a moment that it is only the .NET 4 control which is being used within VS all the time then you can possibly imagine that some controls may now have more properties in .NET 4 than what they use to have in the previous framework versions… For example let us take Login control in .NET 2.0 vs the same control in .NET 4… ClientIDMode did not use to exist in .NET 2.0 but does in .NET 4.

property grid filtering  In this case VS 2010 needs to make sure that those extra properties are not shown in the control property grid as shown above, coz if they do and someone accidentally sets them then they will appear as part of the .aspx/.ascx markup and will get deployed to the web server… As on the web server the app will be set to run in .NET 2.0 it will not recognize the ClientIDMode property and will throw an exception causing production failures. 

One additional goals of Web MT was to ensure that if at all there are any accidental mistakes then they are caught well early within VS rather than letting them propagate and have the application fail at runtime…

In fact I would say that it would be a cardinal sin for Web MT if VS 2010 design time allowed you to create an app which will fail after deployment and the teams over here have done whatever it takes to make sure that does not happen…

Switching C# & VB compilers for the correct Framework Versions – As I mentioned earlier based on the correct framework version the correct C# & VB compilers need to be invoked so that correct binaries can be produced for your projects… This also ensures that VS 2010 is able to catch errors in the C# & VB code based on the compiler features for the particular framework version… 

From compilation standpoint there are different things that happen for Web Application Projects (WAPs) as compared to Web Site Projects (WSPs) which I have explained in the article WAPs vs Web Sites and so there are is a interesting design on how the compiler switching happens in case of these different project systems… I will explain that in a future article but for now you can be rest assured that when you target .NET 3.5 VS 2010 will produce binaries which will run on .NET 3.5 and when you use .NET 4 VS 2010 will produce binaries which target .NET 4…:-)

Add Reference Dialog Filtering – When you try to add new references to your projects to any of the assemblies now you will notice that you will see the references associated with the correct framework version… Again this list is populated by querying reference assemblies similar to what toolbox and property grid filtering did…

In Add Reference dialog box again the validation is done against your project and you are shown only the references which are legit to be added to your project based on its .NET Framework version… 

You will also notice that the path of the Framework assemblies will be pointing to Reference Assemblies folder as shown below:

Add Reference

One of the big challenges that the team faced was trying to improve the performance as compared to VS 2008 while incorporating all these architectural changes around the meta data only assemblies…  The design of  reflecting upon the “Reference Assemblies” and then filtering out .NET 4 assemblies to finally populate the dialog boxes, tool boxes, property grids etc certainly is a lot more work as compared to simply looking at a fixed folder location that was being done in VS 2008…   I am really proud of our team who have spent countless amount of time in fine tuning the flow of these designs to ensure that performance is not adversely affected and hopefully in future builds of VS 2010 you will notice the perf improvements since Beta1 build…

Using the correct machine.config and root web.config

Many of you might be already aware that the web.config file that you see in your web project is actually part of a hierarchical config system…  There is machine.config as well as root web.config which resides in CONFIG folder under “%Windows%\Microsoft.NET\Frameworks\Vx” directory…   Actually an interesting piece to note is that for .NET 2.0, 3.0 and 3.5 the CLR version was always 2.0 and hence the machine.config and root web.config file was never changed since .NET 2.0, check out the “Config” folder for .NET 2.0, if you go to v3.0 or 3.5 you will not find any “Config” folder at all:

image

For .NET 4.0 you will have a similar folder and it will contain “machine.config” and “web.config” files… In essence .NET 4 is the first opportunity for ASP.NET to have a different root web.config and machine.config… Certainly that brings a huge set of advantages but increases the work we needed to do from Web MT standpoint. 

Now when you create .NET 2.0/3.0 or 3.5 project in VS 2010 then the machine.config and root web.config needs to be picked up from .NET 2.0 folder but if you create .NET 4 project then the machine.config and root web.config needs to be picked up from .NET 4 folder…  In nutshell when you start typing <appSettings> and so on in your web.config file do note that the schema intellisense that you get is also customized to the correct config hierarchy that you are in.

If you have incorrect settings in web.config file (which might be correct for a different Framework) then you get errors because of this work in Web MT to use the config files from the correct Framework hierarchy…

Picking correct version of Visual Studio Development Server (Cassini)

As you know we have Visual Studio Development Server (aka Cassini) which ships for local development of web projects within VS… In VS 2010 we will ship with two versions of Cassini EXEs, if you observe system tray balloons/pop-ups you will now notice either webserver40.exe or webserver20.exe… That is because Cassini runs outside the process of Visual Studio and for debugging your .NET 2.0/3.0/3.5 you actually want to run under CLR 2.0 and to try your .NET 4.0 apps you need to run under CLR 4.0… This will provide real framework experience during F5/Ctrl+F5 and View in Browser scenarios… Apart from various bug fixes that went into Cassini 4 this was another chunk of work for our QA team did to verify whether VS 2010 picked up correct version of Cassini or not…

There are several other things related to Multi targeting that I would like to ramble about, but if I do it right now it will just become too long to be read, instead I will hold off for now and continue  with Part 2 in next few days…

Till then my hope is that you will look at that small drop down box a little more next time and remember us all :-)

-Vishal

The remaining posts in the Web MultiTargeting Series are:

10 comments:

Balaje Sankar said...

That was real detailed post on MT. Thanks. Is this the same emulation process happens if I run a .net 2.0/3.x application on a machine hosting .net 4.0 runtime..? Reference assembly might take care of assemblies, but how is the binary compatibility taken care..?

-Balaje Sankar

Jags said...

Very nice elementary points regarding MT. Thanks a lot.

Anonymous said...

Interesting and informative about what VS 2010 offers and some good insights.

Vishal R Joshi said...

Balaje, within VS 2010 you will need .NET 2.0, 3.0 to create applications which target .NET 2.0/3.0... i.e. just with .NET 4 it will not be allowed to target .NET 2.0/3.0/3.5... That said VS 2010 will always come with .NET 4 so a scenario of .NET 4 not existing on VS 2010 box is less likely...

If you are talking about runtime (i.e. without VS in picture)then you will need .NET 2.0 to run .NET 2.0 projects and .NET 4 to run .NET 4 projects... i.e. runtime uses what your app pool is set if it is set as .NET 2.0 then that is what the app will run against and same applies to .NET 4... If you make your .NET 2.0 apps to run under .NET 4 then they should run as .NET 4 apps hopefully without any issues due to backward compatibility...
I hope I answered your question...
-Vishal

Unknown said...

This is a great Blog post. Explains really well what is happening. Thanks for taking the time to write all this up. We are going to be qorking with VS2010 for the next few years and it is nice to have someone explain all this.

Vishal R Joshi said...

Am in the process of writing remaining Multi-targeting feature sets, hopefully that will interest folks as well...
-Vishal

Balaje Sankar said...

Vishal, Thanks for the detailed reply too.
Actually, I didnt put the question right. My mistake. But you got it right.

>>>>If you make your .NET 2.0 apps to run under .NET 4 then they should run as .NET 4 apps hopefully without any issues due to backward compatibility...

Yes, I was looking to know how is the backward compatibility that makes .net 4.0 runtime to run .net 2.0 apps in a webserver implemented. Is it the same or similar emulation process used in MT..?

Otherwise, waiting for the part 2 for your blog on MT.

-Balaje Sankar

Vishal R Joshi said...

Hi Balaje, there is no emulation process at runtime... If you set your app to use .NET 4 in the IIS App Pool then that means you are using .NET 4, the app is treated as if it was created as ASP.NET 4 app to begin with... All the dependent assemblies like System.Web etc will be loaded from GAC and .NET 4 versions of them will be picked, so you will start getting ASP.NET 4 behavior throughout the app... Typically one will not notice any behavior difference due to a very strong backward compatibility... :-)
-Vishal

Anonymous said...

Why would I need this ?

Vishal R Joshi said...

>>> Why would I need this ?
Perhaps you do not need to know about any of this stuff... As long as you are able to develop you web projects well in VS 2010 that is all matters :-)