Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How target framework really works (and why lib for 2.0 can use lib for 4.0)?

Tags:

c#

.net

We have a web ASP.NET application with target framework 4.5.1, which references some library built with target framework 2.0. So, 4.5.1 can use 2.0, that's okay.

But both app and library uses log4net 1.2.11 and app uses package for 4.0 framework, when library uses package for 2.0 framework.

Here how it looks:

Application [4.5.1] --> Library [2.0]
     |                     |
     V                     V
  log4net [4.0]        log4net [2.0]

When I build application, in bin folder I have: app.dll, library.dll and log4net.dll. And log4net here is built targeting 4.0 framework. So here is the question: how library.dll (built targeting 2.0) is using log4net (built targeting 4.0) in this situation? Is it because runtime is 4.5.1 and targeting frameworks means nothing, all code is executed in 4.5.1 context?

like image 340
VorobeY1326 Avatar asked Nov 10 '22 16:11

VorobeY1326


1 Answers

There are a few things at play here.

First, there is the common language infrastructure (CLI). The CLI is a standard for representing metadata about an assembly, about types in the assembly, about fields, methods, properties, events, etc. in the types, and in addition the intermediate language (IL) code implementing the methods which is also part of the CLI standard.

Second, there is the runtime environment, the common language runtime (CLR) for .NET Framework or dotnet for .NET Core. The runtime actually runs an assembly built according to the CLI standard by interpreting the metadata and compiling the IL code into machine code on the fly, as well as introducing things beyond the standard such as the behavior of probing for assemblies and where to find them

Third, there is the .NET Framework runtime libraries. There is nothing particularly special about these libraries; they are just a collection of assemblies. .NET Core also has its own set of runtime libraries. The CLR uses the .NET Framework runtime libraries, and dotnet uses the .NET Core runtime libraries. They are just shared implementation between different applications which everyone developing for a particular platform can rely on.

Finally, there is the target framework. While the proper framework runtime libraries are determined by the CLR / dotnet, this is not necessarily what you build against. That is to say the build engine, not the runtime environment, determines the locations of the libraries used at build time. In particular, there are sets of libraries stripped of the IL code, containing only the metadata, called reference assemblies for each framework you may reference. The build environment knows how to find these. The APIs in the framework you can use are restricted by the choice of your target framework.

How does this all come together? Well, runtime libraries can implement reference assemblies, that is the .NET Framework 4.5.1 runtime libraries contain all of the implementation for the .NET Framework 4.5.1 reference assemblies, but since Microsoft maintains backward compatibility, they also contain all of the implementation of all previous .NET Framework versions. In fact, .NET Framework 4.5.1 implements the .NET Core 1.0 reference assemblies, which in turn implement .NET Standard 1.2 reference assemblies and others. If I compile three libraries against .NET Standard 1.0, .NET Core 1.0, and .NET Framework 4.5, they will all work in the same app running on my PC with .NET Framework 4.6.2 runtime libraries because these libraries encompass all of the APIs for all of my target frameworks.

.NET Standard? This set of reference assemblies is unique in that no canonical library implementation of it exists, and there is no corresponding runtime environment. It is implemented by .NET Framework, .NET Core, Mono, Xamarin, and others. It is meant to be a point of unification, a standard on which all developers may rely no matter where their library or app is going to be executed.

like image 78
Void Star Avatar answered Nov 15 '22 06:11

Void Star