Open tmat opened 7 years ago
//cc @ericstj
cc @piotrpMSFT @krwq @dsplaisted There is a similar requirement for the CLI team
Also there need to be a way how to specify the target framework for which the redirects need to be generated. Is there is a way to do so for a class library?
this issue is blocking me from using Microsoft.AspNetCore.TestHost in a .net 4.6.1 test project targeting asp.net core .net 4.6.1 in VS 2017. Manually adding the binding redirect attributes to my test proj doesn't help. :(
The magic sauce seems to be to add
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
but I don't understand why there are two props with basically the same meaning. I found this here
and then my libraries started generating binding redirects.
But now it stopped working again.... totally inconsistent behavior :(
Oh yes it does. I've figured it out. ;) When set the below on a library project
<PropertyGroup>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
(1) If there are no binding conflicts then the *.config file is not generated. (2) If there are binding conflicts then the *.config file is generated.
Over here I tried to activate both
`
` but no effect.
Also, no effect either in library or exe file. Like... redirects not created at all.
If you don't need the binding redirects then it will not generate them. At least that is what I have found.
I need them. That's why my software does not start.
I am also suffering from this. I get the MSB3276 warning, but adding
``
This should work:
<Target Name="ForceGenerationOfBindingRedirects"
AfterTargets="ResolveAssemblyReferences"
BeforeTargets="GenerateBindingRedirects"
Condition="'$(AutoGenerateBindingRedirects)' == 'true'">
<PropertyGroup>
<!-- Needs to be set in a target because it has to be set after the initial evaluation in the common targets -->
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
</PropertyGroup>
</Target>
tmat, it does work, thank you! Is there any way to see which binding redirections were made?
Yes, there should be a .dll.config file generated to the output directory.
Fixing this (not requiring any specific output type) is required to unblock https://github.com/Microsoft/vstest/issues/792
tmat, although I said it worked earlier, I was mistaken, I had changed the command line directory to another project and didn't realize I was building something that didn't have MSB3276 to begin with. At this point, I am still getting that warning, even when using the Target
solution. Sorry about that...
To be honest, I think what I am experiencing is an issue with the warning showing up even when the binding redirection is being done...so the warning trigger is being too sensitive...
I do get the .dll.config
file with the correct redirections, either using the Target
technique, or any other technique that sets the AutoGenerateBindingRedirects to be turned on.
I might have to find a more appropriate issue to discuss this... thanks for the help so far, though!
@tmat Your solution worked for me... thank you so much! So now the redirects are created. Surprising to see how many... I envision it's going to be a hard time to work with .NET Standard libraries. Based on the fallacy of interoperability between frameworks and platforms....
It shouldn't need to be set in a target since the common targets only set it to true, never to false (am I missing something?). At least it worked for a few users on SO: https://stackoverflow.com/questions/43995432/could-not-load-file-or-assembly-microsoft-extensions-dependencyinjection-abstrac/43996389 https://stackoverflow.com/questions/43955266/interface-in-netstandard-1-1-library-does-not-have-implementation-in-net-4-61/43955719
I am aware it worked for others. But for me the only thing that worked was setting it with the target solution @tmat proposed. The rest did not generate any binding at all.
To understand why static properties might be different than the target you can look at the evaluated project by using msbuild /pp. I suspect that the order of import and/or the contents of the targets themselves differs between the projects.
/cc @bradwilson
I might have a duplicate issue here: https://github.com/dotnet/sdk/issues/1595
Edit:
I've done extensive tests (see my issue in https://github.com/dotnet/sdk/issues/1595) and the problem is related to using Package References but not explictly setting both
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
and
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
in the project file.
@MichaelKetting in my case that did not influence anything. Unfortunately.
I would like to not have to put either of these in a .csproj targeting .NET Framework, regardless of output type. If the output type is DLL, I want a .config by default even if it's not a test DLL. It's critical information no matter where the DLL is used.
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
Right now (VS 15.4) I have to add both to every project.
@jnm2 You could add them to a single Directory.Build.props file that will be picked up by every project underneath its directory.
@nguerrera I hadn't thought of that, that's a nice workaround. But at the end of the day, I don't want to have to do either (or tell other people to do either in order to use my NUGet packages).
@AndyGerlicher can we get this fixed in 15.6? There is a lot of customer pain around getting non-exe test projects to generate binding redirects. I think the conditions on $(GenerateBindingRedirectsOutputType) should be removed. If AutoGenerateBindingRedirects is true, then generate irrespective of output type. cc @Petermarcu
Agree this is critical for getting test libraries to work correctly in a Net Standard world.
AFAIK, none of the test frameworks support netstandard
, and for good reason: it's not a platform, it's an API set. A netstandard
library is not intended to be "runnable".
I wouldn't mind being able to build a netcoreapp1.0 test DLL and execute it against .NET Core 1.0, 1.1, 2.0, etc. Likewise, I wouldn't mind being about to build a netstandard1.3 test DLL and execute it against those as well as .NET Framework, Xamarin, etc.
I wouldn't mind being about to build a netstandard1.3 test DLL and execute it against those as well as .NET Framework, Xamarin, etc.
That's currently very very hard to achieve - test hosts rely on the build system to produce the necessary assets for each platform. From generation of deps.json/runtimeconfig.json for .net core to netstandard shim injection for .net framework.
Such a "portable test" project would need runners that create projects behind the scenes referencing the test project / dlls.
This issue reflects the need to run build logic meant for "executable projects" for tests.
It is indeed possible to do this. The .NET SDK just doesn't support it currently. The Compile task can be executed once on the netstandardXX project and the results can then be deployed multiple times with corresponding runtime configuration files to mutliple deployment directories, one per target platform. I could easily imagine the project having settings like
<TargetFramework>netstandard1.3</TargetFramework>
<DeploymentFrameworks>net46;netcoreapp2.0<DeploymentFrameworks>
Then the unit test runners would run for each deployment framework.
I wouldn't mind being able to build a netcoreapp1.0 test DLL and execute it against .NET Core 1.0, 1.1, 2.0, etc.
This is fine.
Likewise, I wouldn't mind being about to build a netstandard1.3 test DLL and execute it against those as well as .NET Framework, Xamarin, etc.
This is not. You should use multi-targeting instead.
This is not. You should use multi-targeting instead.
I disagree. Why not? Just because it's hard for tooling authors?
Then the unit test runners would run for each deployment framework.
A full build is required. Just multi-target and be done with it. These suggested workarounds are, frankly, nonsense in the world where we have <TargetFrameworks>
. dotnet xunit
already supports multi-targeting against both net452
+ and netcoreapp1.0
+ (example: https://github.com/xunit/xunit.integration/blob/master/dotnet-xunit/v2x_MultiTarget_DotNetSdk.csproj). This is what all multi-platform test runners should support.
I disagree. Why not?
Because, as stated above, netstandard
is an API set, not a platform. Unit tests require a platform to run on, and without knowing the platform it will be run on, the build system as it stands today (and presumably for a short- to medium-term future) requires that knowledge to properly build for the platform.
Whether you agree with the decision the team made is irrelevant (today), as that's the world we live in. You want this to work today? Multi-target.
Whether you agree with the decision the team made is irrelevant (today), as that's the world we live in. You want this to work today? Multi-target.
Oh, I'm being totally realistic. I know multi-targeting is the only way to go right now. But you told me it's not fine to want to be able to run a .NET Standard binary against a selection of platforms and versions and I disagree. I don't think it's wrong to want to be able to execute a single DLL against more than one platform and version, whether the API set targeted is netcoreapp. or netstandard. or net*. Yes, some map to platforms and one doesn't, but at the end of the day they are all just API specs.
As an example, though I wouldn't likely find this useful in the real world, a net46 test dll could be executed against .NET Framework and .NET Core 2.0.
Multi-targeting the tests is the opposite of what I want. My tests can be written against Net Standard which means it can run on any runtime. Multi-targeting is a way to limit my tests to a very specific set of platforms. That's the opposite of portable code.
It means every time a new platform comes out i have to modify my tests to support it. Even though I've done nothing to the code other than say "hey this new platform exists".
I've spoken with the CLI and testing teams a couple of times about this. The preferred setup here is:
Both 2 and 3 should be done anyways. They are general improvements to the ecosystem. Taken together though it makes authoring Net Standard test libraries a reality.
And it'll come as no surprise then that I want the same capabilities for netstandard console apps. In fact, not being able to do this is causing us at NUnit to have to create a matrix of separate csproj files, a cross product between unique DLLs targeting different frameworks and the list of platforms each unique DLL can be executed on. The new SDK doesn't really provide a way to relieve the complexity yet, but I think @tmat's proposed <DeploymentFrameworks>
is exactly the type of thing I've been looking for.
Any news on this issue?
Ugly workaround, but much nicer than creating a bunch of separate .csprojs: https://github.com/dotnet/sdk/issues/1561
@jaredpar
- Allow test libraries to target net standard
- Allow publishing to target libraries and exe projects
- Extend publishing to allow for targets not explicitly listed in the project file
I would like to be able to follow these in an issue other than this one which isn't strictly related.
I was struggling to run NUnit tests on TeamCity while worked fine locally. Adding <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
seemed to resolve my issue and I finally got the needed redirects to appear on Project.Tests.dll.config
on TeamCity as well. (Thank you @bradphelan & others <3)
I'm still a bit confused why it worked locally already only with <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
? Has this been addressed with some version of MSBuild already?
Note that web projects with web.config are incompatible with GenerateBindingRedirects because the edits have to be made to web.config in source. For these projects, you are instead supposed to double click on warnings in the error list to get web.config edited. It looks to me as though if we were to remove all consideration of GenerateBindingRedirectsOutputType, then we would regress the web.config case.
As I posted on https://github.com/dotnet/standard/issues/613#issuecomment-354393350, this will look like this:
For me the solution was to add
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.8.0" />
to a unit test project
@dsyme I'm pretty sure that package sets the OutputType to Exe
@dsplaisted Only for netcoreapp
.
In my case, the problem was caused by conflict of GenerateBindingRedirects and TransformXml (XDT transformation) msbuild targets. By default TransformXml overrides output of GenerateBindingRedirects.
<TransformXml Source="$(IntermediateOutputPath)$(TargetFileName).config" Destination="$(IntermediateOutputPath)$(TargetFileName).config" Transform="App.$(Configuration).config" />
This solved my problem.
I've having a similar issue, not sure if it's the same one. Can you guys confirm if this matches your situation?
When I build the project, binding redirects are applied to the output config file. But, all the warnings still occur. It's as if the binding redirects are being added at the wrong stage of compilation.
The property is ignored unless the containing project is an .exe.
Extensible frameworks/apps that load plugins might support loading configuration for each plugin, including binding redirects, from a .dll.config file next to the plugin .dll. For example, a unit-testing framework such as xunit. See also proposal https://github.com/Microsoft/msbuild/issues/1309, which might also make use of this feature.
I propose the restriction on project type is removed and binding redirects are generated for any project that sets AutoGenerateBindingRedirects to true.