Friday, July 1, 2011

Quick Tip: Fixing those Stubborn References

I am working on a project that uses a mixed set of assemblies. Some are in the .NET Framework 3.5, and others are in version 4.0. The project is being converted to use the Managed Extensibility Framework (MEF). In order for the parts to play nicely together, all projects must use the same version of the System.ComponentModel.Composition.dll assembly.

The problem is that MEF is a part of the core framework in 4.0. When you add a reference, there is a set of internal pathways that Visual Studio uses to resolve the location. Even if you browse to a local version of the DLL, as I did, once it is added the core framework version ends up being referenced.

The solution is simple but not straightforward. To fix any reference that keeps bouncing back to the GAC or framework version, follow these steps:

Unload the Project

We'll need to edit the project file itself, and that is not possible while it is loaded in the Solution Explorer. Right-click on the project node, and choose "Unload project." The project should go to slightly grayed and show (Unavailable) next to it.

Edit the Project

Now, right-click the project again and you'll receive a different context menu. This time, choose "Edit (projectname).csproj" and you will see the XML for the project file itself. Parts of project files are grouped in a tag called ItemGroup and you should find one that contains references, like this:

 <ItemGroup>
    <Reference Include="PresentationCore" />
    <Reference Include="PresentationFramework" />
    <Reference Include="System.ComponentModel.Composition" />
 </ItemGroup>

Change to an Explicit Reference

The first step to making the reference lock is to make it explicit. The generic reference above will find the framework version. Instead, change it to the explicit version - in this case, the version of MEF that was released in Februrary 2010 just prior to being integrated into the full framework. The new reference looks like this:

<Reference Include="System.ComponentModel.Composition, Version=2010.2.11.0, Culture=neutral, processorArchitecture=MSIL"/>

Provide a Hint Path

Finally, if the assembly is being packaged with the project, it can help to let Visual Studio know where to find it. This is done with a hint path. To add the hint, simply open the tag and then add the relative path to the assembly from the current project (if you have to use an absolute path, your solution won't transfer well to other machines including the build box).

In this example, there is a higher level folder named "External" that holds external references, so the full reference with the hint path looks like this:

<Reference Include="System.ComponentModel.Composition, Version=2010.2.11.0, Culture=neutral, processorArchitecture=MSIL">
  <HintPath>..\External\System.ComponentModel.Composition.dll</HintPath>
</Reference>

Now you can save and close the project. Right-click on the project and choose "reload" project to make it available again, then right-click on the reference and view the properties to verify it is now "locked" to the version you want.

Jeremy Likness