Designer Filtering using Reference Assemblies


This is the second in my blog series on Visual Studio 2010 Designer Multi-Targeting.

Visual Studio 2010 expands multi-targeting support to include metadata filtering in features such as intellisense and the property grid.  Notice how the property grid filters out the new ClientIDMode property added to web controls in .NET 4 when targeting .NET 2:

.NET 4:
PropertyGrid4_0
.NET 2:
PropertyGrid2_0

So, how is this happening when Visual Studio itself is running on .NET 4?  The answer is reference assemblies!

Reference assemblies are metadata-only assemblies that have method bodies and non-public members stripped out in order to make them more compact.  As such, they can’t be loaded for execution by the CLR.  However, the multi-targeting infrastructure is able to load and unload these assemblies as needed and has all the information it needs to provide target-aware reflection.

Compare the Button.OnClick event from the release and reference assemblies:

Release assembly:
OnClickRuntimeAssembly
Reference assembly:
OnClickMetadataOnlyAssembly 

Reference assemblies are organized by target framework under the directory:

%ProgramFiles%\Reference Assemblies\Microsoft\Framework\{Framework}\{Version}

Multi-targeting also supports targeting framework profiles, which are subsets of the full framework.  For instance, a new Windows Forms application will now target the 4.0 Client profile by default.  This Client profile excludes server-specific assemblies such as System.Web.dll.  Profile reference assemblies are located under the directory:

%ProgramFiles%\Reference Assemblies\Microsoft\Framework\{Framework}\{Version}\Profile\{Profile}

Note that assemblies for versions prior to .NET 4 do not follow this rule.  For these, the multi-targeting infrastructure will load and unload the release assemblies from legacy installation folders, including the following:

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727

%ProgramFiles%\Reference Assemblies\Microsoft\Framework\v3.5

Multi-targeting will also recognize assemblies from any designer extension directories registered using the AssemblyFoldersEx registration.


Comments (2)

  1. Anonymous says:

    Do you happen to know if there's any public API that can be used to get the actual path to .net assemblies? Or do you know how VS translates reference assembly path to the real path before compilation?

  2. IVsFrameworkMultiTargeting will resolve assemblies for a given target framework.  You can get this instance from the global VS service provider.

    Alternatively, you can get IVsDesignTimeAssemblyResolution from the project's service provider.  This resolver resolves both framework assemblies for the project's target framework as well as any project references.  Note that this resolver will return paths based on the actual project references and may not account for any shadow copying that is done by VS.

    For more information on Visual Studio assembly resolution, check out this blog series:

    blogs.msdn.com/…/resolveassemblyreference