-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Binding redirect in multi-target class library. #20584
Comments
I found this saying that binding redirection is gone for it just gives warnings. But in my case above, THIS IS NOT JUST WARNING!. It can't bind the right DLL, so that there is not "async and await" in net40, so it won't compile!. |
@ericstj @terrajobst any advice? |
Those old packages were never intended to work with the new nuget. BCL.Build used a powershell script to install its targets which is no longer supported, it then relied on nuget installing reference items with hintpaths to find the references to redirect, which no longer happens. There's some hacking you could do to make this work but I think manually defining the redirects might be easier. Microsoft.BCL.* packages could consider an update to better work with the new nuget, but most of these are obsolete now that .net 4.0 is out of support. @jarenduan if you want configuration specific redirects, just create a file named something like app.net40.config, then set the AppConfig property to point to that only when targeting net40, for example: <AppConfig Condition="'$(TargetFramework)' == 'net40'">app.net40.config</AppConfig> When I did this with the following content of the app.net40.config it worked for me: <?xml version ="1.0"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.IO" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.6.8.0" newVersion="2.6.8.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration> |
@ericstj Thanks for the analysis and suggestion, I believe you are right. However, I did the app.net40.config thing as you said, and still got the errors. When it worked for you, is there any "async/await" code in your project? If I compile an empty multi-target project, it will pass the compilation with a few warnings, but it will fail if I write some "async/await" codes. I am also considering dropping the net40 support, and suggest my users update to net45 or even higher. But only trouble is net40 supports XP, and net45 requires Win7. So net45 is not a perfect upgrade for net40. |
@jarenduan can you paste the code you have to add to empty project to get it failing? The "line" which makes it from OK to broken. That would help us reproduce inhouse. |
@ericstj like this: using System;
using System.Threading.Tasks;
namespace AsyncForNet40 {
public class Class1 {
public static async Task Run(Action action) {
await Task.Factory.StartNew(action);
}
}
} The csproj: <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net40;netstandard1.4</TargetFrameworks>
<AppConfig Condition="'$(TargetFramework)' == 'net40'">App.net40.config</AppConfig>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net40' ">
<PackageReference Include="Microsoft.Bcl.Async" Version="1.0.168" />
<Reference Include="System" />
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
</Project> The app.net40.config is same as you posted. And in output window:
Failed. |
If you're getting those warnings it means the binding redirects are not correct. Let me share the exact project that worked for me. |
It looks like you also need to set <AutoUnifyAssemblyReferences Condition="'$(TargetFramework)' == 'net40'">false</AutoUnifyAssemblyReferences> Previously this was set by the BCL.Build targets which aren't being imported as I mentioned above. With those two settings I can successfully build your sample. Gist is here: |
@ericstj, thank you for your generous help. It works! I've learned from your solution that remember to examine the building target of the old packages when there're something wrong. Thanks to everyone got involved. You guys did a very good job. |
Thanks @ericstj for guidance! I didn't follow all technical details - is there anything we could/should do in product (e.g. tooling) or in docs to make the experience better? |
@karelz, well, some old packages rely on install.ps1/init.ps1 to do some stuffs, and according to my understanding, these scripts are not supported in the new version of Nuget. I guess we should consider including these changes in the nuget docs. And speaking of tooling, we now have nuget/dotnet/msbuild all in vs2017. I believe they are not exactly the same as each other. It seems like there is a little bit confusion about when to use which. It'd best provide a unified tooling experience. |
How do i redirect the assembly binding in a multi-target class library, such as:
That can be done by app.config in traditional .Net class library. But what about a multi-target class library?
BTW, this issue comes from referencing Microsoft.Bcl.Async when I try to multi-target net40 and netstandard1.4:
And VS2017 gave the warning:
According to Microsoft.Bcl.Async FAQ, it seems like binding redirecting is needed.
The text was updated successfully, but these errors were encountered: