How do I prevent .NET 4.7.1 libraries from copying the facade dlls to the bin folder?
Asked Answered
I

3

7

I'm certain there's probably a bunch of things going on here that I don't understand well enough, so forgive me if this is a stupid question or if there's obvious details missing.

I have a Visual Studio 2015 solution that I've upgraded from .NET 4.5.1 to .NET 4.7.1. The solution consists of a website (not web app) project, and several libraries. The libraries don't really have any dependencies (except eachother) and while they are targeting .NET 4.7.1, they don't use, need, or reference .NETStandard.Library.

When I compile one of the libraries in particular, it keeps copying a bunch of .NET 4.7.1 facade dlls into the website bin folder. Unfortunately, the website is a Kentico 11 application, and it keeps trying to load the System.IO.Compression.ZipFile facade, and chokes on it because it's a reference assembly, not a real assembly.

If I delete the .dll, everything runs fine... but I don't want to delete it every time or add a post-build event to delete it. That's just silly.

Can anyone help me understand what's going on here, and how to clean it up?

Inguinal answered 21/3, 2018 at 21:46 Comment(3)
As a temporary workaround, I've added the actual System.IO.Compression.ZipFile dll as a reference even though it's not used. That way the real dll is there instead of a facade, and Kentico doesn't choke on it. Still feels dirty, but at least it works.Inguinal
Do you have test code in your projects? Something that would need a facade?Paranoia
Targeting 4.7.1 in VS2015 is pretty courageous, it doesn't know beans about these netstandard dll hell inducers. You might well be ahead if you explain why changing the target was necessary.Droit
T
4

Kentico 11 can only target up to .NET 4.7 so in an attempt to fully support your .NET 4.7.1 libraries I believe it is copying in those additional facade DLLs. This is based on the .NET 4.7.1 release announcement, specifically this section:

BCL – .NET Standard 2.0 Support

.NET Framework 4.7.1 has built-in support for .NET Standard 2.0. .NET Framework 4.7.1 adds about 200 missing APIs that were part of .NET Standard 2.0 but not actually implemented by .NET Framework 4.6.1, 4.6.2 or 4.7. You can refer to details on .NET Standard on .NET Standard Microsoft docs.

Applications that target .NET Framework 4.6.1 through 4.7 must deploy additional .NET Standard 2.0 support files in order to consume .NET Standard 2.0 libraries. This situation occurred because the .NET Standard 2.0 spec was finalized after .NET Framework 4.6.1 was released. .NET Framework 4.7.1 is the first .NET Framework release after .NET Standard 2.0, enabling us to provide comprehensive .NET Standard 2.0 support.

https://blogs.msdn.microsoft.com/dotnet/2017/10/17/announcing-the-net-framework-4-7-1/

Reference that led me to this conclusion: https://github.com/Particular/NServiceBus/issues/5047#issuecomment-339096350

Update:

I was unable to reproduce your issue in Visual Studio 2017 Version 15.6.2.

I installed a Kentico 11 website project targeting .NET 4.7. I then created a library project that targeted .NET 4.7.1. I added some dummy code to the project to make use of Sysetem.IO.Compression and System.Net.Http namespaces. I added a reference to the project from Kentico and ran a build. No facade DLLs where copied to the bin folder.

This post indicates the issue was fixed in Visual Studio version 15.6 https://github.com/dotnet/sdk/issues/1647#issuecomment-364999962

Throw answered 22/3, 2018 at 17:3 Comment(5)
I think you're right. That all makes a lot of sense. I guess I'll just have to leave it with the weird workaround I have in place right now, and hope that's something that gets resolved down the road.Inguinal
@Inguinal Are you able to have your libraries target 4.7 instead? At least until Kentico adds support for 4.7.1.Throw
If I fought really hard with the client, maybe I could convince them... but as long as I delete that one .dll it actually appears to work just fine targeting 4.7.1 - so for now I'm just going to stick with the workaround I think.Inguinal
@Inguinal I have updated my answer with some additional findings. If the workaround is in place and working for you that is good. If you do end up using or needing functionality from those namespaces then you might want to update Visual Studio to prevent issues.Throw
Thanks for the research! Hopefully we'll upgrade to 2017 soon anyway, but we just haven't yet.Inguinal
N
2

The additional files that get deployed to your bin folder are needed to support referencing and running .NET Standard 1.x and .NET Standard 2.0 libraries in your .NET Framework application.

We have documented this as a known issues with .NET Framework 4.7.1.

The presence of those additional files is not sufficient however. You also need to have binding redirects generated in order to ensure types correctly unify across libraries.

Visual Studio 15.6.3 (and later) have a change that will automatically generate those binding redirects for your application.

.NET Framework 4.7.2 addresses the issues that require those additional files to be deployed with your application. When targeting or running on .NET Framework 4.7.2 you won't have any additional files copied to your bin folder and no binding redirects will be automatically generated.

You can try .NET Framework 4.7.2 and see what's new by following the instructions here.

Nabila answered 29/3, 2018 at 16:53 Comment(1)
also logged as an issue at github.com/dotnet/standard/issues/415#issuecomment-315798357Pattypatulous
C
1

References to assemblies have their own properties. You can specify there if you want to copy the assembly to the build output directory. Maybe somewhere it is set to true. To check that go to Solution Explorer in Visual Studio and right click on the referenced assembly. Then click Properties and look for property named "Copy Local".

Chieftain answered 21/3, 2018 at 22:46 Comment(2)
I'm familiar with these settings - the problem is that this dll isn't a referenced assembly. It's being injected by Visual Studio when it calls csc.exe - it isn't in the list of references because I don't use it or need it.Inguinal
@Inguinal OK, I didn't notice your earlier comment. Unfortunately I don't have experience with newer versions of .Net framework. If you don't want that dll in your references maybe you can delete it in postbuild event but that's just another workaround.Chieftain

© 2022 - 2024 — McMap. All rights reserved.