Each DLL in .NET Core 2.0 SDK comes in two copies (they have different content and file size). For instance:
"c:\Program Files\dotnet\sdk\2.0.0\Microsoft\Microsoft.NET.Build.Extensions\net461\ref\System.Threading.Thread.dll" (14432 bytes)
"c:\Program Files\dotnet\sdk\2.0.0\Microsoft\Microsoft.NET.Build.Extensions\net461\lib\System.Threading.Thread.dll" (14352 bytes)
What's the difference between them (and the purpose of having two)?
The process of locating an assembly involves the following steps: If a <codeBase> element is found in the application configuration file, the runtime checks the specified location. If a match is found, that assembly is used and no probing occurs. If the assembly is not found there, the binding request fails.
One of the things I did miss was a clear direction on how to reference a . NET dll directly (and of course still enjoy the benefits of intellisense), basically the same thing as doing Project > Add Reference > Browse in Visual Studio. And that's it!
Reference assemblies are usually distributed with the Software Development Kit (SDK) of a particular platform or library. Using a reference assembly enables developers to build programs that target a specific library version without having the full implementation assembly for that version.
An assembly is a collection of one or more files and one of them DLL or EXE. DLL contains library code to be used by any program running on Windows. A DLL may contain either structured or object oriented libraries. A DLL file can have a nearly infinite possible entry points.
So as Hans Passant already mentioned, "reference" assemblies are used to build programs, which means that this is the assembly that is passed to the compiler as a reference. At runtime however, the implementation might be different. Apart from the framework itself, this may be used by any NuGet package that distributes a single compile-time reference assembly but a variety of implementation assemblies for each target (.NET Core, .NET Framework, MonoAndroid etc.). The lib
folder in NuGet packages can even be used to add more private implementation assemblies that it doesn't want consuming applications to reference directly.
Reference assemblies only have "stub" methods so that the available API surface is defined and can be inspected by the compiler.
However, you are mentioning the Microsoft.NET.Build.Extensions
folder. It follows the structure of a NuGet package (since that is how it is built and integrated into the SDK), but it has a completely different purpose than a normal library you'd use. It is used to allow .NET Standard libraries to run on partly-compatible versions of .NET Framework. It works by adding the implementation assemblies to the build output - but these are a special as they only forward to corresponding .NET Framework types and add API surface that throws PlatformNotSupportedException
for types that are available in .NET Standard but not implemented by the .NET Framework. E.g. a .NET Standard 1.* library would reference System.Object
from System.Runtime.dll
and a .NET Standard 2.0 library would reference it from netstandard.dll
. The Microsoft.NET.Build.Extensions
contains both a System.Runtime.dll
and a netstandard.dll
that contain type forwarding declarations to forward to .NET Framework's mscorlib.dll
. This works similar for other types and assemblies.
These assemblies are only added when necessary. .NET Framework 4.7.1 will contain all these assemblies and forwards so no additional files will be added to the build output.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With