Easily override NuGet DLL in development (VS 2015)

2019-07-11 08:13发布

问题:

We have 3 solutions in VS 2015 containing C# projects. One of those creates a NuGet package and the other 2 reference a DLL from that NuGet package. (The DLL contains the interface between two parts of an application.) A TeamCity build server builds the DLL and the NuGet package, automatically setting its version.

In development I want to be able to easily test changes to the DLL without committing them and waiting for the package to be built. What's the best way to do this? Ideally I want to say: if C:\Build\My.dll exists then use it regardless of its version, otherwise use version 1.2.3.4 of the MyDLL NuGet package. Is there any way to specify that and have it "survive" NuGet upgrades?

I tried temporarily deleting the reference to that DLL and adding a reference directly to the version I want, but the problem is that it's referenced in many projects and doing this for all of them is quite a hassle.

回答1:

Looks like it can be done in the BeforeBuild step by removing the existing NuGet reference. This way, the NuGet reference item itself is unchanged and can be freely replaced by NuGet during upgrades, but during the build my version of the DLL gets used (if it exists).

It also takes a slight hack to remove the reference regardless of version.

  <Target Name="BeforeBuild">
    <!-- Override NuGet package with a local copy in dev, if available -->
    <PropertyGroup>
        <ReplacementLocalDllPath>Some\Path\My.dll</ReplacementLocalDllPath>
    </PropertyGroup>
    <ItemGroup Condition="Exists($(ReplacementLocalDllPath))">
      <!-- Remove any version of the DLL to be replaced -->
      <ReferenceToBeRemoved Include="@(Reference)" Condition="$([System.String]::Copy(&quot;%(Reference.Filename)&quot;).StartsWith('My'))" />
      <Reference Remove="@(ReferenceToBeRemoved)" />
      <!-- Add the local DLL, ignoring its version -->
      <Reference Include="My, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
        <SpecificVersion>False</SpecificVersion>
        <HintPath>$(ReplacementLocalDllPath)</HintPath>
      </Reference>
    </ItemGroup>
  </Target>


回答2:

You can use conditional references in your csproj file at achieve this. Check out this MSDN link for more info: MSBuild Conditional Constructs