Summary:
I'm writing a library that depends on Polly and I discovered that the moment I add polly as a package reference it suddenly brings System.Net.Http 4.2.0.0. This is a very painful well known issue on .net (see this) and I wouldn't like the consumers of our library to go through it, it forces them to write obscure assembly redirects and if they don't they may (this is the annoying part) have runtime issues depending on the GAC of the system.
Expected behavior:
Polly shouldn't bring any System.Net.Http dependencies since is not listed on the dependencies of their nuget package: https://www.nuget.org/packages/Polly/
Actual behaviour:
This is the output of ildasm of a testing library after adding polly as a dependency and using httpclient:
.assembly extern System.Net.Http
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
.ver 4:2:0:0
}
Steps / Code to reproduce the problem:
A very simple library project should reproduces this:
TestingPolly.csproj
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>TestingPolly</RootNamespace>
<AssemblyName>TestingPolly</AssemblyName>
<TargetFramework>net461</TargetFramework>
<Platforms>x64</Platforms>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<!-- Try removing Polly -->
<PackageReference Include="Polly" Version="7.1.0" />
<PackageReference Include="System.Net.Http" Version="4.3.3" />
</ItemGroup>
</Project>
Class1.cs
using System.Net.Http;
namespace TestingPolly
{
public class Class1
{
private HttpClient foo;
}
}
After building the project, running this command on the output directory of the project (on the VS developer command prompt) with the polly package ildasm TestingPolly.dll /OUT=testingpolly.txt && notepad testingpolly.txt will output this:
.assembly extern System.Net.Http
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
.ver 4:2:0:0
}
If polly is removed, ildasm will output this (expected since we depend on System.Net.Http):
.assembly extern System.Net.Http
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
.ver 4:1:1:2
}
Polly contains no reference to System.Net.Http. Searching the Polly repo for http confirms there is no reference to System.Net.Http.
Polly supports .Net Framework via .NET Standard targets. My assumption is that the bridge from .NET Standard to .NET Framework for .NET4.6.1 is bringing in (that version of) System.Net.Http indirectly - _and/or_ that the MsBuild tooling is messing up the versions (as the issue you linked suggests). This is not something Polly can control; it is on the Microsoft side.
Are either of (1) and (2) below options for you?
(1) Add an explicit reference to System.Net.Http, the version you want to use, to your top-level project. (From the Steps / Code to reproduce which you quoted and the issue you linked, I suspect this may not be ~a complete~ any solution.)
(2) Upgrade to / support only .NET 4.7.2. This is a Microsoft recommendation (see footnote 2 here) for those on .NET4.6.1-4.7.1. Because of the widely documented issues with .NET Framework 4.6.1-4.7.1 projects consuming .NET Std packages.
If those are not an option, a third option could be to explore whether this (3) would help:
(3) Add explicit .NET Framework targets to Polly
If you wish to explore (3), please could you trial and report back whether this resolves your case or not. You can pull the Polly codebase from github to your local machine, add explicit framework targets as you require here, run the build, and trial the nuget package which is generated in the artifacts\nuget-package folder. Start from the head of this branch, not master.
Based on reading https://github.com/dotnet/corefx/issues/25773, I cannot confidently say that (3) would solve the issue for you (the problem may still be caused by the interaction of MS Build/GAC and depend on the end-user's version of Visual Studio/MS Build).
_If_ (3) resolves your issue, it could be another reason for us to add .NET Framework targets to Polly. We have been reluctant to do this, because it will force us to add a .NET Framework 4.7.2 target also (so that nuget does not downgrade those users to .NET4.6.1 dependencies); and that would change the .NET 4.7.2 experience to consuming framework instead of .NET Standard 2.0. That is a (theoretically) unnecessary change for .NET 4.7.2 users, but the nuget tooling would force us to do it.
I haven't been working in .NET Framework for some months now, so all community feedback is welcome.
I tried variations of 1) but didn't work. I think the best approach we should take is 2) as is recommended by MS and .net is moving forward.
Having said that, I'll give it a shot to 3) and will let you know my findings.
All right, so I've tried adding the 461 target (branch here). Indeed the manifest looks like what I'm expecting on the minimal repro library after using the nuget built locally:
.assembly extern System.Net.Http
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
.ver 4:1:1:2
}
Thanks! Good to know. Ok, I will consult with the other Polly team key stakeholder whether we are good to add .NET Framework targets back in, seems like it would help here.
@afcruzs We experienced the same. @jglinsek tracked down a way to resolve it in the short-term by adding an explicit binding redirect to downgrade system.net.http to 4.0.0.0
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
This may not work for your use case but, if so, it might be a way forward in the short-term. This issue affects us on 461 and 472.
Polly v7.2.0 has been published with .NET Framework targets 4.6.1 and 4.7.2 now supported natively as part of the nuget package. Should resolve this issue.