プリミティブ(II)の.NETコア深い理解 - 共有フレームワーク

オリジナル:ディープダイブ.NETコアプリミティブに共有フレームワーク:パート2
著者:ネイトマクマスターの
翻訳:.NETコアプリミティブの深い理解(B) -共有フレームワーク
の:Lamond陸

Benpianは前に「翻訳:deps.json、runtimeconfig.json、dllファイルプリミティブ.NETのコアの深い理解、一部のコンテンツおよび.NETのコア3.0がありますが、フォローアップ、わずか3を書いた一時的なこの一連の、」もはや互換性はなく、原則のほとんどは同じではないので、私は翻訳で三分の一をバックアップします。

序文

.NETコア以降1.0ので、共有フレームワーク(共有フレームワーク)は、.NETのコアの重要な部分となっています。以降.NETコア2.1ので、ASP.NETコアは、最初の共有フレームワークとして登場しました。あなたは、このことに気づいたことがないかもしれないが、それのデザインは、我々は繰り返しと継続的な議論の多くを通り抜けました。この記事では、我々は共有フレームワークを掘り下げ、多くの場合、一部の開発者に遭遇した落とし穴のいくつかを説明します。

基礎編

スタンドアロンモード(内蔵型) - .NETコアアプリケーションは、2つのモードで実行してもよいし、各モードはフレーム(従属フレームワーク)に依存しています。私のMacBookには、独立してASP.NETコアのWebアプリケーションを実行するの最小値が、約350の文書があり、合計ファイルサイズは93メガバイトです。これとは対照的に、最小限の依存アプリケーションフレームワーク、約5ファイル、合計サイズが239キロバイト

あなたは、次のコマンドラインは、2つの異なるモードに基づいて生成されて使用することができます。

dotnet new web
dotnet publish --runtime osx-x64 --output bin/self_contained_app/
dotnet publish --output bin/framework_dependent_app/

ときにプログラムが実行され、その機能は同じです。したがって、これら二つのモデルは持っているとの違いは何ですか?実際には、としては、文書の公式ウェブサイトで説明しました:

配備依存フレーム(フレームワークに依存配置)に依存する.NETコアターゲット共有コンポーネントがインストールされています。システムにインストールされているターゲット共有コンポーネントに依存しない独立した展開(自己完結型の展開が)、プログラムに必要なすべてのコンポーネントは、現在のアプリケーションに含まれています。

この公式文書(https://docs.microsoft.com/en-us/dotnet/core/deploying/異なるモードの利点の非常に良い説明で)。

PSは:側では、興味のある学生が自分自身を見ることができます(FDE)フレームワークに依存する実行可能ファイルを導入することなく、記事を書かれました。

共有フレームワーク

ここでは、簡単に言えば、.NET Frameworkがコア共有アセンブリ(* .dllファイル)ディレクトリのコレクションがある、これらのアセンブリは、あなたの.NETのコアアプリケーションディレクトリに表示されている必要はありません。このディレクトリには、.NETのコアの共有システム全体のバージョンの一部であり、通常、あなたが可能C:\Program Filres\dotnet\sharedでそれを見つけます。

あなたが実行するdotnet.exe WebApi1.dllコマンドを、.NETのコアのホストプログラム

  • あなたのアプリケーションは、アセンブリ名とバージョンを頼る探してみてください
  • 一部ではアセンブリ内の固定位置を探してみてください

これらのアセンブリは、フレームを共有に限定されるものではなく含む、多くの異なる位置で見つけることができます。私の以前の記事で、私は、主要であればことを説明deps.jsonし、runtimeconfig.json行動プロファイリングホストプログラム。学生は、あなたが記事を閲覧することができ、詳細をお知りになりたいです。

.NETのコアのホストプログラムは、読み込み*.runtimeconfig.json負荷分散フレームワークのバージョンを確認するためにファイルを。このように、このファイルの内容:

{
  "runtimeOptions": {
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "2.1.1"
    }
  }
}

ここでは、名前が名前だけで共有フレームワークです。慣例により、名前がに基づくべきで.App終わりますが、実際には、このような「FooBananaShark」として任意の文字列とすることができます。

バージョン共有の枠組みについて、ここでは最小限のバージョンで構成されています。.NETコアホストプログラムは、後で構成、共有積載枠の対応するバージョン、または共有フレームに基づいて、それは負荷分散フレームワークの指定されたバージョンよりも低くなることはありません。

だから、私はフレームワークを共有どのような最終的には、それをインストール?

ランはdotnet --list-runtimes、お使いのコンピュータにインストールされているフレームワーク、並びにそれらのバージョンとファイルの場所を共有するかを確認することができます。

コントラストMicrosoft.NETCore.AppAspNetCore.AppおよびAspNetCore.All

ここでは、.NETのコア2.2、例えば。

フレーム名 説明
Microsoft.NETCore.App 実行時の基礎。これは主申し出System.ObjectList<T>stringクラス、およびメモリ管理、ファイル管理、ネットワークI / O、スレッド管理およびその他の機能
Microsoft.AspNetCore.App デフォルトのWebランタイム。これは主に、関数の主要部分はKestral、MVC、SignalR、カミソリ、とのEFコアを含むWebサーバーを、作成するためのAPI関数の使用を提供します。
Microsoft.AspNetCore.All サードパーティのライブラリとの統合。これは、EFコア+のSQLiteのサポート、ならびにそのようなので、上のRedis、アズールキーValutやなどの拡張機能の数を追加しました。(もはや.NETコア3.0で使用されません)

リレーションシップの共有フレームワークとパッケージNuget

.NETのコアSDKには、生成されruntimeconfig.jsonたファイルを。.NETコア1及び2において、二つのセクションを使用して、SDKプロジェクトの構成が決定runtimeconfig.jsonフレームのファイル部分。

  • MicrosoftNETPlatformLibraryプロパティ。すべての.NETのコアプロジェクトについては、デフォルトでいますMicrosoft.NETCore.App
  • 結果セットNugetのパッケージ管理ツールを復元し、結果セットには、同じ名前のパッケージが含まれていてもよいです

ここでは、すべての.NETのコアプロジェクトのために、.NETのコアSDKは、パッケージへの暗黙の参照を追加しますMicrosoft.NETCore.AppASP.NETコアは、デフォルトの設定を変更することでMicrosoftNETPlatformLibrary、それを変更しますMicrosoft.AspNetCore.App

しかし、Nugetパッケージ管理ツールが!が共有するための任意のフレームワークを提供していない共有するための任意のフレームワークを提供していない、注意すべきである!共有するための任意のフレームワークを提供していません!^ _ ^ 3回を言うために重要なことを。Nugetパッケージ管理ツールは、コンパイラが使用するAPI、および小型SDKの一部だけを提供しています。ソースは、フレームワークのランタイムのインストーラを共有することができますhttps://aka.ms/dotnet-download、またはVisual Studio、ドッカーミラーだけでなく、Azureのサーバの一部にバンドルされています。

戦略を圧延前のバージョン

私は上記の、通りruntimeconfig.jsonが、最低限のバージョンを指定します。実際のリリースは、レース戦略の使用についての詳細はで見つけることができます(以前のバージョンによって異なります公式ドキュメントを。たとえば、

  • アプリケーションの最小バージョンは、共有フレームワーク2.1.0を使用している場合は、フレームワークプログラムのバージョンは、最高のシェアは2.1でロードされます。*。

この部分については、「:深い理解のruntimeconfig.json .NETコアプリミティブ(III)の深い理解」を参照してくださいすることができます

著者:「.NETのコアプリミティブの深い理解は、(III):の深い理解runtimeconfig.jsonは」上のフォローアップ

階層化フレームワークを共有します

.NETコア2.1リリースの階層フレームワークの共通の特徴を導入します。

フレームワークを共有する他の共有フレームワークに依存してもよいです。この機能は、パッケージは、共有メモリのフレームに変換されたときに、この機能を実行することができ、ASP.NETコアをサポートするために組み込まれています。

あなたが見れば$DOTNET_ROOT/shared/Microsoft.AspNetCore.All/$version/、フォルダ、あなたはというファイル見つけるMicrosoft.AspNetCore.All.runtimeconfig.json次のように読み込むファイルを、

$ cat /usr/local/share/dotnet/shared/Microsoft.AspNetCore.All/2.1.2/Microsoft.AspNetCore.All.runtimeconfig.json
{
  "runtimeOptions": {
    "tfm": "netcoreapp2.1",
    "framework": {
      "name": "Microsoft.AspNetCore.App",
      "version": "2.1.2"
    }
  }
}

マルチレベルの検索

.NETコア2.0の多段検索特性を導入します。

ホストプログラムは、適切な共有の枠組みを見つけるために、複数の位置にプロービングを開始します。DOTNETは最初含まれているルートディレクトリを探しdotnet.exe、実行ファイルのディレクトリを。ここでは、設定することができDOTNET_ROOT、この構成環境変数をオーバーライドします。この構成によれば、取得するための最初のディレクトリは以下のとおりです。

$DOTNET_ROOT/shared/$name/$version

このディレクトリが存在しない場合は、ホストプログラムは、グローバルリストの所定のパスを取得するの多段検索機構を使用しようとします。このメカニズムは、グローバル変数を設定することにより行うことができるDOTNET_MULTILEVEL_LOOKUP=0シャットダウンします。次のようにデフォルトでは、所定のグローバルパスリストは以下のとおりです。

THE ロケーション
ウィンドウズ C:\Program Files\dotnet(プロセス64) C:\Program Files (x86)\dotnet工程32)(ソースの表示
マックOS /usr/local/share/dotnetソースを表示
Unixの /usr/share/dotnetソースを表示

最後のホストプログラムは、見つけることがグローバルディレクトリに以下のディレクトリを検索します

$GLOBAL_DOTNET_ROOT/shared/$name/$version

ReadyToRunプロパティ

アセンブリ共有フレームワークは、それが対象となるcrossgenツールは、事前に最適化されました。アセンブリの「ReadyToRun」バージョンを生成することができ、このツールを使用して、これらのアセンブリは、所与のオペレーティング・システムとCPUアーキテクチャのために最適化されています。ここでの主なパフォーマンスの向上は、起動時にかかるJITコードを削減する用意があります。

Crossgen関連文書:https://github.com/dotnet/coreclr/blob/v2.1.3/Documentation/building/crossgen.md

いくつかの落とし穴

私はすべての.NETのコアのプログラマは次のトラップのいくつかに遭遇すると信じています。私が生成する方法でこれらの問題を説明しようとします。

HTTPエラー502.5プロセス障害

これまでのところ、トラップの開発者は、最も頻繁に遭遇するか、AzureのWebサービスは、IISでASP.NETコア・アプリケーションでホストされています。この問題は通常、プロジェクトをアップグレードするために、開発者に発生した、またはアプリケーション・デプロイメント・ターゲット・マシンが更新されていないとき。エラーの本当の原因は、通常、アプリケーションのフレームワークで必要なバージョンが正常に起動しない、.NET Coreアプリケーションで、その結果、見つけることができない共有されています。ときにdotnetアプリケーションを開始できません、IISは、HTTP 502.5エラーを返すが、内部エラーメッセージが表示されます。

「指定されたフレームワークが見つかりませんでした」

It was not possible to find any compatible framework version
The specified framework 'Microsoft.AspNetCore.App', version '2.1.3' was not found.
  - Check application dependencies and target a framework version installed at:
      /usr/local/share/dotnet/
  - Installing .NET Core prerequisites might help resolve this problem:
      http://go.microsoft.com/fwlink/?LinkID=798306&clcid=0x409
  - The .NET Core framework and SDK can be installed from:
      https://aka.ms/dotnet-download
  - The following versions are installed:
      2.1.1 at [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
      2.1.2 at [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]

このエラーは通常、HTTP 502.5エラー、障害またはVisual Studioのテストエクスプローラー後に発生します。

とき、前述したようにruntimeconfig.json、ファイルは、フレームワークの名前とバージョンを指定しますが、プロパティとマルチレベルのロールフォワード戦略を取得した後、ホストはまだ時間の適したフレームワークのバージョンを見つけることができない、上記のエラーが発生します。

アップグレードMicrosoft.AspNetCore.App組立Nugetパッケージを

Microsoft.AspNetCore.AppNugetバッグアセンブリ、共有フレームワークを提供していません。これは単に、APIだけでなく、少量のSDKの一部を使用するためにC#/ F#コンパイラを提供します。あなたは一人で共有フレームワークをダウンロードしてインストールする必要がありますので。

同時に、原因ロールフォワード戦略には、共有フレームワークの新バージョンで実行するようにプログラムを合わせてNugetパッケージの最新バージョンを必要としません。

これは設計上のエラーASP.NETコアチームであってもよいし、我々はプロジェクトファイルに表示さNugetパッケージとしてのフレームワークを共有することはできません。パッケージによって提供されるフレームワークを共有しているパッケージは、通常の意味ではありません。異なるパッケージの中で最もプログラムとは異なり、彼らは自給自足ではありません。私たちは、プロジェクトの使用時にことを願ってい<PackageReference>た時間は、Nugetができ、必要なすべての参照をインストールすることではなく、イライラはこれらの特別なパッケージのデザインは我々の期待モデルから逸脱していることです。もちろん、今、私たちはこの問題を解決するための様々な提案を持っています。私はそれを早い時期願っています。

<PackageReference Include="Microsoft.AspNetCore.App" />

ASP.NETコア2.1の新しいプロジェクトテンプレートと文書では、Microsoftが開発者に披露した、彼らは唯一のプロジェクトファイルに次のコード行を追加する必要があります。

<PackageReference Include="Microsoft.AspNetCore.App" />

他の<PackageReference>参照コードが含まれていなければならないVersion特性を。プロジェクトファイルがある場合のみ、<Project Sdk="Microsoft.NET.Sdk.Web">最初に、上記のフレーズは、パッケージの参照バージョンとは何の関係が動作しませんおり、ここだけのためのMicrosoft.AspNetCore.{App, All}アセンブリパッケージ作品。ウェブは、例えば、他の設定項目をSDK:<TargetFramework><RuntimeIdentifier>自動的にパッケージの適切なバージョンを選択します。

あなたのいくつかは、パッケージで引用参加するにした場合Versionの特性、およびバージョンを指定するか、またはあなたがこの機能を使用することはできません、プロジェクトファイルの先頭としてのWeb SDKを使用しないでください。ここで私はこれを達成するための最良の方法は、プロジェクトのレベルや種類のご理解に基づいているので、それは難しい、良い解決策をお勧めする見つけます。

投稿トリム(トリミングを公開)

あなたが使用している場合dotnet publish、コマンドは発行されたカタログに表示されるべきかを決定するためにアセンブリ(結果を復元)Nugetの結果を復元するために使用されるアプリケーションに依存し、SDKのためのフレームワークを発行しました。彼らはすでに共有枠に表示されますので、いくつかのアセンブリはNugetコピーにより、アセンブリパッケージであり、いくつかはしません。

ASP.NET共有フレームワークとしてCoreとNugetパッケージが利用可能であるため、これは、いくつかのエラーを生成するのは簡単です。プロジェクトのリリースは、特性は、グラフィカルな数学的推移の依存関係、およびアップグレード、およびので、右のパッケージファイルを選択してチェックしようとしますトリム。

ここでは、次の例へのプロジェクト参照を持っています:

<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.9" />

MVCは、実際にあるMicrosoft.AspNetCore.Appの一部が、あなたが呼び出すときにdotnet publishプロジェクトを発行するためのコマンドを、あなたのプロジェクトは、アップグレード後に選択したことがわかりますMicrosoft.AspNetCore.Mvc.dllパッケージ、よりも、このパッケージMicrosoft.AspNetCore.App最終的なので、2.1.1バージョンに含まれているが、高いMicrosoft.AspNetCore.Mvc.dll公開にコピーされますディレクトリ。

アプリケーションのサイズが成長しているとして、あなたが取得することはありませんので、これは、理想的ではないReadyToRun最適化されたバージョンをMicrosoft.AspNetCore.Mvc.dll

PS:この質問以前に少し気づいたが、本当に普通。

ターゲットフレームワークのニックネームと共有の枠組みを混乱させる

私たちは単純に考えるならば"netcoreapp2.0" == "Microsoft.NETCore.App, v2.0.0"、あなたは間違っています。のみプロジェクトファイルによってターゲット・フレームワークのニックネーム(ターゲットフレームワークモニカはTFMをいう)を<TargetFramework>指定されたノード。「netcoreapp2.0は、」あなたに.NETのコアのバージョンを表示するには、人間に優しい方法を望んでいました。

その名が短すぎることTFMトラップ。これは様々な共有フレームワーク、コントロールの特定のパッチの旧バージョン、バージョンローラ、出力タイプを発現し、独立した公開またはフレームワークがコンテンツの公開を依存していることができません。SDKは、TFMからの設定の数を推測しようとしますが、すべてを推測することはできません。

だから、より正確に、「netcoreapp2.0は」「Microsoft.NETCore.App v2.0.0デベロッパー以降」を意味します。

プロジェクト構成を混乱させる

最後に、トラップおよび関連プロジェクト構成。ここでは専門用語や設定名がたくさんある、彼らは常に一貫していません。これらの用語は、非常に混乱しているので、あなたは、これらの用語を混同している場合、あなたのせいではありません、問題ではありません。

以下は、私はいくつかの一般的なプロジェクト設定とその実用的な意味合いを一覧表示します。

<PropertyGroup>
  <TargetFramework>netcoreapp2.1</TargetFramework>
  <!--
    实际意义:
      * 从Nuget包解析编译引用时使用的API集合的版本
  -->

  <TargetFrameworks>netcoreapp2.1;net471</TargetFrameworks>
  <!--
    实际意义:
      * 使用两个不同的API集合版本进行编译。但这并不代表多层共享框架
  -->

  <MicrosoftNETPlatformLibrary>Microsoft.AspNetCore.App</MicrosoftNETPlatformLibrary>
  <!--
    实际意义:
      * 最顶层的共享框架名称
  -->

  <RuntimeFrameworkVersion>2.1.2</RuntimeFrameworkVersion>
  <!--
    实际意义:
      * 指定了Microsoft.AspNetCore.App程序包的版本,这个版本就是最小的共享框架版本
  -->

  <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  <!--
    实际意义:
      * 操作系统种类 + CPU架构
  -->

  <RuntimeIdentifiers>win-x64;win-x86</RuntimeIdentifiers>
  <!--
    实际意义:
      * 运行此项目可能使用的操作系统种类和CPU架构列表,你必须要通过RuntimeIdentifier配置选择其中一个
  -->

</PropertyGroup>

<ItemGroup>

  <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.2" />
  <!--
    实际意义:
      * 使用Microsoft.AspNetCore.App作为共享框架
      * 最低版本2.1.2
  -->

  <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.2" />
  <!--
    实际意义:
      * 引用Microsoft.AspNetCore.Mvc程序包
      * 实际版本2.1.2
  -->

  <FrameworkReference Include="Microsoft.AspNetCore.App" />
  <!--
    实际意义:
      * 使用Microsoft.AspNetCore.App作为共享框架.
  -->

</ItemGroup>

概要

オプション機能として共有.NET Frameworkのコア、欠陥があるけれども、私はほとんどのユーザーのために、これは妥当なデフォルト設定だと思います。私はまだ私は、これは共有フレームワーク機能の良い概要です願って、.NETのコア開発者が基本原理を理解することは良いことだと思います。あなたはより多くの情報を見つけることができるように私は、関連する文書の数を試してみましたが、公式サイトを案内します。その他の質問がございましたら、以下のコメントを投稿してください。

おすすめ

転載: www.cnblogs.com/lwqlun/p/11802513.html