In-depth .NET Core basis - 1: deps.json, runtimeconfig.json and dll

In-depth .NET Core basis: deps.json, runtimeconfig.json and dll

Original Address: https://natemcmaster.com/blog/2017/12/21/netcore-primitives/

1. .NET Core Application Infrastructure

I learned to use gcc, C ++ programming and vim. When I started using C # and .NET, click Visual Studio in the 运行button is magic, but also with those who despair. Disappointed - not because I want to write Makefile - but because I do not know 运行what has been done. So, I began to explore. In this post, I will show most of the basic tools used in .NET Core in and manually create .NET Core applications without the aid of Studio Visual . If you are new to .NET Core, and hope to uncover insider, this article is for you to come. If you are already a .NET Core developers and curious * .deps.json * .runtimeconfig.json file or what to do, I will cover these contents.

I will end Visual Studio magic, and has been using the command line tool. For you can be, you need to

Core 2.1 SDK the .NET (In fact, the .NET 3.1 Core SDK has been released, I think you should download the latest version). The following these steps is done on macOS, but they also work the same on Linux and Windows, if you change the path c:\Program Files\dotnet\and dotnet.exewords.

2. C # compiler

C # compiler to compile the * .cs file * .dll files, also known as assembly file. Assembly file is portable executable file format, .NET Core can execute it on Windows, macOS and Linux. .NET Core appIt is a collection of a series of * .dll files (including a small amount of configuration file). It can be a variety of programming languages, such as F # VB or the like generated, however, C # is the most commonly used.

C # compiler can direct calls to generate an assembly file. C # compiler in .NET Core SDK can be found in, and this is called as follows.

dotnet /usr/local/share/dotnet/sdk/2.1.3/Roslyn/bincore/csc.dll -help

Let us provide an input content for it. First, create a named Program.csfile, and write the following C # code:

/* Program.cs */
class Program
{
   static void Main(string[] args)
       => System.Console.WriteLine("Hello World!");
}

Then, at the command line, execute the following command:

> dotnet \
/usr/local/share/dotnet/sdk/2.1.3/Roslyn/bincore/csc.dll \
 -reference:/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/System.Runtime.dll \
 -reference:/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/System.Console.dll \
 -out:Program.dll \
Program.cs

In .NET Core 3.1, the NuGetFallbackFoleralready from the sdkremoved folder. These assemblies have been transferred to the C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1folder.

If in Windows, pay attention to handling spaces:

dotnet 'C:\Program Files\dotnet\sdk\3.1.100\Roslyn\bincore\csc.dll' -reference:'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Runtime.dll' -reference:'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Console.dll' -out:Program.dll Program.cs

Meaning of the parameters are as follows:

  • dotnet - C # compiler itself is a .NET Core application, so we need to start it by dotnet command

  • /usr/local/share/dotnet/sdk/2.1.3/Roslyn/bincore/csc.dll - path C # compiler. On Windows, the path is: C: \ Program Files \ dotnet \

  • -reference parameter points to the System.Runtime.dll and System.Console.dll, which is similar to C ++ header files in, they provide information on the compiler System.Objectand System.Consoleinformation.

  • -out: Program.dll, the output file name. .dllThe extension is .NET Core convention, not a requirement. If not specified, the compiler will generate the name Program.exeof the file. On Windows systems, which can lead to a misunderstanding, because you can not double-click Program.exe to start it, so in .NET Core, we always use the .dll extension.

Reference thousands of reference allows us to use other types defined in the code .NET Core code involved, for example List, Integerand HttpClientthe type and the like. But you have to tell the compiler where to find them. If you delete the -reference:***section, the compiler will fail and return the following error:

Program.cs(1,11): error CS0518: Predefined type 'System.Object' is not defined or imported
Program.cs(3,26): error CS0518: Predefined type 'System.String' is not defined or imported
Program.cs(3,16): error CS0518: Predefined type 'System.Void' is not defined or imported

Path used in the example is /usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app. These come with Microsoft.NETCore.Appthis NugGet package, we will discuss it later.

3. runtimeconfig.json

For .NET Core application, the runtime.config.jsonfile is required. Term runtime, shared frameworkor platformthey are often used interchangeably, however, when talking about .NET Core, which is one thing. The JSON configuration file for the runtime.

If you have a step on the assembly obtained, you can try to run it from the command line, through the dotnettool. Without this runtime.config.json, the attempt will fail:

dotnet Program.dll
A fatal error was encountered. The library 'libhostpolicy.dylib' required to execute the application was not found in '/Users/nmcmaster/code/'.

In .NET Core 3.1 environment Windows environment, I get is:

 dotnet Program.dll
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:\temp\dotnet\'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the C:\temp\dotnet\Program.runtimeconfig.json file specifying the appropriate framework.

This section declares mean, .NET Core can not find the file used to perform certain files Program.dll necessary. To solve this problem, create a named Program.runtimeconfig.jsonfile, and use the following:

{
 "runtimeOptions": {
   "framework": {
     "name": "Microsoft.NETCore.App",
     "version": "2.0.0"
  }
}
}

Note that in .NET Core .3.1, document reads as follows:

{
 "runtimeOptions": {
   "framework": {
     "name": "Microsoft.NETCore.App",
     "version": "3.1.0"
  }
}
}

These settings indicate dotnetusing the Microsoft.NETCore.App 3.1.0shared frame. The framework most commonly used in the frame, but there are other frame, for example Microsoft.AspNetCore.App. The .NET Framework is not installed machine-range force, there may be multiple shared .NET Core Framework installed on the same machine. dotnetReads the JSON file and /usr/local/share/dotnet/shared/$FrameworkName/$Version/find the desired file and run the application.

Note: If you have a later version of Microsoft.NeTCore.Appthe patch is installed, for example shared/Microsoft.NETCore.App/2.0.4/, dotnetwill automatically use later.

Now, execution dotnet Program.dll.

>dotnet Program.dll
Hello world!

4. Package wrapped

Providing the packages between the different items, and shared between team organization among code, .NET assemblies packaged into *.nupkga file, this is just a ZIP format file and an XML file containing (.nuspec) , it contains metadata about the package.

The most popular package called a .NET JSON.NET, also known as Newtonsoft.Json. It provides serialization and parsing of JSON API. We can get it to disk and extract from NuGet.org.

Bash # 
mkdir -p ./packages/Newtonsoft.Json/10.0.3/
curl -The https://www.nuget.org/api/v2/package/Newtonsoft.Json/10.0.3 | of -xf - -C ./packages/Newtonsoft.Json/10.0.3/

Windows environment

# Windows (powershell)
mkdir ./packages/Newtonsoft.Json/10.0.3/
Invoke-WebRequest https://www.nuget.org/api/v2/package/Newtonsoft.Json/10.0.3 -OutFile Newtonsoft.Json.10.0.3.zip
Expand-Archive Newtonsoft.Json.10.0.3.zip -D ./packages/Newtonsoft.Json/10.0.3/

To demonstrate its use, we will update the previous step sample code to output JSON object format.

class Program
{
   static void Main(string[] args)
     => System.Console.WriteLine(
         Newtonsoft.Json.JsonConvert.SerializeObject(new { greeting = "Hello World!" }));
}

This need to add more parameters to the parameter list compiled compiler in order to use Newtonsoft.Json the API.

> dotnet /usr/local/share/dotnet/sdk/2.1.3/Roslyn/bincore/csc.dll \
   -reference:/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/System.Runtime.dll \
   -reference:/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/System.Console.dll \
   -reference:/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/System.Collections.dll \
   -reference:./packages/Newtonsoft.Json/10.0.3/lib/netstandard1.3/Newtonsoft.Json.dll \
   -out:Program.dll \
  Program.cs

.NET Core 3.1 using the following command:

dotnet 'C:\Program Files\dotnet\sdk\3.1.100\Roslyn\bincore\csc.dll' -reference:'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Runtime.dll' -reference:'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Console.dll' -reference:'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Collections.dll' -reference:'./packages/Newtonsoft.Json/10.0.3/lib/netstandard1.3/Newtonsoft.Json.dll' -out:Program.dll Program.cs

Note: Obviously we need reference:Newtonsoft.Json.dll, but why System.Collections.dll? This is because we also use the anonymous type new { greeting }. Behind, C # compiler generates an anonymous type on a .Equals()method call System.Collections.Generic.EqualityComparer, which is defined in System.Collections.dllthe.

Compilation should be successful, though with a few warnings.

Program.cs(4,35): warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'Newtonsoft.Json' matches identity 'System.Runtime, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy

In .NET Core 3.1, in fact, I get the following output:

Microsoft (R) Visual C# Compiler version 3.4.0-beta4-19562-05 (ff930dec)
Copyright (C) Microsoft Corporation. All rights reserved.

warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'Newtonsoft.Json' matches identity 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
Program.cs(5,11): warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'Newtonsoft.Json' matches identity 'System.Runtime, Version=4.2.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy

This means Newtonsoft.Jsonthe creation of Newtonsoft.Json.dlltime, based on his System.Runtime.dllversion is 4.0.20.0. But, now offers System.Runtime.dllupdated some version 4.2.0.0. If the version 4.0.20.0to 4.2.0.0change between technology will lead to the application you're running problems, so the compiler warning. Fortunately, these changes are backward compatible, it Newtonsoft.Jsonwill work fine. We can add parameters -nowarn:/CS1701to suppress these warnings.

> dotnet /usr/local/share/dotnet/sdk/2.1.3/Roslyn/bincore/csc.dll \
   -reference:/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/System.Runtime.dll \
   -reference:/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/System.Console.dll \
   -reference:/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.0.0/ref/netcoreapp2.0/System.Collections.dll \
   -reference:./packages/Newtonsoft.Json/10.0.3/lib/netstandard1.3/Newtonsoft.Json.dll \
   -nowarn:CS1701 \
   -out:Program.dll \
  Program.cs

For .NET Core 3.1 under the Windows environment, the command is as follows:

dotnet 'C:\Program Files\dotnet\sdk\3.1.100\Roslyn\bincore\csc.dll' -reference:'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Runtime.dll' -reference:'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Console.dll' -reference:'C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\3.1.0\ref\netcoreapp3.1\System.Collections.dll' -reference:'./packages/Newtonsoft.Json/10.0.3/lib/netstandard1.3/Newtonsoft.Json.dll' -nowarn:CS1701 -out:Program.dll Program.cs

Note that CS1701the letters are capitalized.

5. Dynamic Link

In the previous step, we have compiled a reference Newtonsoft.dll, System.Runtime.dllsimple applications and other assemblies. Added Newtonsoft.dllbefore, our application works well. However, after an updated version, run the program will fail.

> dotnet Program.dll
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified.

.NET runtime dynamic linking assemblies. The compiler in the assembly Program.dlladded to the Newtonsoft.Json.dllreference, but does not copy the code to come. .NET Core look forward to be able to load a program called when the application execution runtime Newtonsoft.Json.dllset of procedures. For System.Runtime.dlland System.Console.dll, as well as other references to the System. * File is the same.

.NET Core can look at a series of locations through configuration Newtonsoft.Json.dll, however, for simplicity, we can copy it to Program.dllthe same file folder.

> cp ./packages/Newtonsoft.Json/10.0.3/lib/netstandard1.3/Newtonsoft.Json.dll ./
> dotnet Program.dll
{"greeting":"Hello World!"}

Why we do not need to System.Runtime.dllcopy over it and other documents? These files are dynamically linked by sharing framework Microsoft.NETCore.App over, as described above.

6. deps.json

deps.jsonFile is dependent on documentation. It can be used to dynamically configure the links from the package assembly. As described above, .NET Core may be configured to dynamically load from a plurality of assembly positions. These locations include:

  • Directory, and the application where the application of the entry in the same folder, requires no configuration.

  • Package cache folder (or cache recovery NuGet NuGet drop folder)

  • After the package cache optimization, storage or run-time package.

  • Service catalog (servicing index), rarely used for Windows Update mode

  • Shared frame (arranged by runtimeconfig.json)

In summary, the deps.jsondefinitions can be dynamically linked dependency list, usually, the file is generated by the machine, for practical applications, can become very large and complex. However, it is plain text, so we can use the editor to handle it.

Add the name Program.deps.jsonof the file to the project, as follows:

{
 "runtimeTarget": {
   "name": ".NETCoreApp,Version=v2.0"
},
 "targets": {
   ".NETCoreApp,Version=v2.0": {
     "Newtonsoft.Json/10.0.3": {
       "runtime": {
         "lib/netstandard1.3/Newtonsoft.Json.dll": {
           "assemblyVersion": "10.0.0.0",
           "fileVersion": "10.0.3.21018"
        }
      }
    }
  }
},
 "libraries": {
   "Newtonsoft.Json/10.0.3": {
     "type": "package",
     "serviceable": false,
     "sha512": ""
  }
}
}

To show how this works, now with the Program.dllclip of the same file Newtonsoft.Json.dlldeletion. Then, execution dotnet Program.dll.

> rm Newtonsoft.Json.dll
> dotnet Program.dll
Error:
An assembly specified in the application dependencies manifest (Program.deps.json) was not found:
  package: 'Newtonsoft.Json', version: '10.0.3'
  path: 'lib/netstandard1.3/Newtonsoft.Json.dll'

While providing Program.deps.jsondocuments, .NET Core need a little more about where to locate the matching deps.jsoninformation file assembly. This configuration may be achieved by one of three ways:

  1. *.runtimeconfig.dev.json. This is typical of the best way to configure. Add File Program.runtimeconfig.dev.jsonfile, in which the location of the package folder. It is similar to Program.runtimeconfig.jsonthe file, but it is optional. Typically contains the full path of the file, it is not suitable for publication on different machines.

     {
      "runtimeOptions": {
        "additionalProbingPaths": [
          "/Users/nmcmaster/code/packages/"
        ]
      }
    }

     

  2. Command Line. You can use the execcommand to manually specify the dotnetlocation of the command assembly. Use --additionalprobingppathparameter can specify multiple values.

    > dotnet exec --additionalprobingpath ./packages/ Program.dll

     

  3. *.runtimeconfig.json. You can add a run-time settings to specify the new location of the probe. It may use a relative path.

    {
      "runtimeOptions": {
        "framework": {
          "name": "Microsoft.NETCore.App",
          "version": "2.0.0"
        },
        "additionalProbingPaths": [
          "./packages/"
        ]
      }
    }

 

Note: In my .NET Core 3.1 environment, this additionalProbingPathsdid not work. Here is a question on StackOverflow: https://stackoverflow.com/questions/56844233/additional-probing-paths-for-net-core-3-migration

7. Summary

For most of the development work, we do not need these foundations. Similarly NuGet, MSBuild and Visual Studio automatically processed to obtain applications, C # file, invoke the compiler, link to the debugger, and other tasks. However, I think that behind how it works is still very used with. Of course, you can also deepened. What there is in actual * .dll files? What is the * .pdb file? What is crossgen and libcoreclr? These I will stay in the other section.

8. References

Guess you like

Origin www.cnblogs.com/haogj/p/12003854.html