Configuration Specific Reference Location

Sometimes there is the need to have references dependent upon the configuration you are currently in.  You may have a dependencies folder that all your applications can access, and you have an assembly per configuration.  So when you are debugging your application, you want to use the project reference for your API, but when you deploy to your testing server, you want to use the testing version of the API, or Staging, or Release, or…well, you get the idea.

The solution to this is quite easy.

The details of our example will be as follows:

  • One solution with two projects
    • Consumer (Console application)
    • ServiceAPI
  • Our solution will have four configurations
    • Debug
    • Test
    • Stage
    • Release
  • Debug will use a project reference
  • Test, Stage, and Release will reference C:\Dependencies\Test, (Or \Stage or \Release)

Once you have your solution set up and configured, add a reference to your ServiceAPI inside your Consumer project.  Now we have the basics setup and are ready to modify our project file to have different API paths depending on our current configuration.

First, right-click on the Consumer project and select, edit project file.  If prompted to save changes to your solution, click Yes.

image

Inside your project file you will see a series of PropertyGroups and ItemGroups.  If you notice, you have one PropertyGroup for each configuration of your project, and an ItemGroup for reference items, one for compile items, and one for project references.

We want our project reference to only be a project reference if we are in Debug mode.  If you look through your project file, you will find something like this:

<ItemGroup>
  <ProjectReference Include="..\ServiceAPI\ServiceAPI.csproj">
    <Project>{94c972f3-2724-4258-a16f-b121d8502a27}</Project>
    <Name>ServiceAPI</Name>
  </ProjectReference>
</ItemGroup>

Add the following Condition attribute to the ItemGroup tag.  One thing to note here is that the Condition argument syntax is the same in both Visual Basic and C#.  The comparison operator used is the C# one and you would use the same even if this is a Visual Basic project.

<ItemGroup Condition="'$(Configuration)' == 'Debug'">
  <ProjectReference Include="..\ServiceAPI\ServiceAPI.csproj">
    <Project>{94c972f3-2724-4258-a16f-b121d8502a27}</Project>
    <Name>ServiceAPI</Name>
  </ProjectReference>
</ItemGroup>

Now, we want the ServiceAPI to have a specific folder based on it’s configuration, so add the following ItemGroup to the XML file:

<ItemGroup Condition="'$(Configuration)' != 'Debug'">
  <Reference Include="ServiceAPI">
    <SpecificVersion>False</SpecificVersion>
    <HintPath>C:\Dependencies\$(Configuration)\ServiceAPI.dll</HintPath>
  </Reference>
</ItemGroup>

The HintPath is the location Visual Studio should look for the dll, and you can use the environment variables there, so you notice the hint path includes $(Configuration).  Now you can reload the project (Right click the project and select “Reload Project”.  If prompted to save, click “Yes”.

In Debug mode, you will notice the ServiceAPI is using the project reference, but as we switch between configurations, the path changes:

Debug Mode:

image

Release Mode:

image

Test Mode:

image

Stage Mode:

image

One thing to note as you cycle through the configurations.  The properties grid doesn’t update as you change configurations, but the project does.  That means if you switch from Test to Stage, the properties window will still stay Test, but the project will be using Stage.  If you click another reference and then click back to ServiceAPI, it will update the properties window and you will see the path is actually changed.

Feel free to leave any questions or comments in the comments section below!

Happy Coding!

Advertisements