次の方法で共有


アセンブリ のバージョンをリダイレクトする

手記

この記事は .NET Framework に固有のものです。 .NET 6 以降のバージョンを含む、.NET の新しい実装には適用されません。

コンパイル時のバインド参照は、.NET Framework アセンブリ、サード パーティ製アセンブリ、または独自のアプリのアセンブリにリダイレクトできます。 別のバージョンのアセンブリを使用するようにアプリをリダイレクトするには、さまざまな方法があります。発行元ポリシー、アプリ構成ファイル、またはコンピューター構成ファイルを使用します。 この記事では、.NET Framework でのアセンブリ バインドのしくみと、その構成方法について説明します。

ヒント

この記事は、.NET Framework アプリに固有のものです。 .NET 5 以降 (および .NET Core) でのアセンブリの読み込みの詳細については、「.NET での依存関係の読み込み」を参照してください。

アセンブリの統一とデフォルトのバインディング

.NET Framework アセンブリへのバインドは、アセンブリの統一 と呼ばれるプロセス介してリダイレクトされることがあります。 .NET Framework は、共通言語ランタイムのバージョンと、タイプ ライブラリを構成する約 22 個の .NET Framework アセンブリで構成されます。 これらの .NET Framework アセンブリは、ランタイムによって 1 つのユニットとして扱われます。 既定では、アプリが起動されると、ランタイムによって実行されるコード内の型へのすべての参照は、プロセスに読み込まれるランタイムと同じバージョン番号を持つ .NET Framework アセンブリに転送されます。 このモデルで発生するリダイレクトは、ランタイムの既定の動作です。

たとえば、アプリがSystem.XML名前空間の型を参照し、.NET Framework 4.5 を使用してビルドされた場合、ランタイム バージョン 4.5 に付属するSystem.XML アセンブリへの静的参照が含まれます。 .NET Framework 4 に付属するSystem.XML アセンブリを指すようにバインド参照をリダイレクトする場合は、アプリ構成ファイルにリダイレクト情報を配置できます。 統合された .NET Framework アセンブリの構成ファイル内のバインド リダイレクトは、そのアセンブリの統合を取り消します。

また、使用可能なバージョンが複数ある場合は、サードパーティアセンブリのアセンブリ バインドを手動でリダイレクトすることもできます。

ヒント

アプリケーションが間接的に参照する NuGet パッケージを更新し、FileLoadExceptionMissingMethodExceptionTypeLoadExceptionFileNotFoundExceptionなどの新しいエラーの表示を開始する場合は、自動バインド リダイレクトを有効にするか、バインド リダイレクトを手動で追加することが必要になる場合があります。 これは、NuGet パッケージを更新する場合は通常であり、一部のパッケージが以前のバージョンの依存関係に対してビルドされた結果です。 次のアプリ構成ファイルの抜粋では、System.Memory パッケージのバインド リダイレクトが追加されます。

<dependentAssembly>
   <assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
   <bindingRedirect oldVersion="0.0.0.0-4.0.2.0" newVersion="4.0.2.0" />
</dependentAssembly>

パブリッシャー ポリシーを使用してバージョンをリダイレクトする

アセンブリのベンダーは、新しいアセンブリにパブリッシャー ポリシー ファイルを含めることで、アプリを新しいバージョンのアセンブリに送ることができます。 グローバル アセンブリ キャッシュにあるパブリッシャー ポリシー ファイルには、アセンブリ リダイレクト設定が含まれています。

アセンブリの major.minor バージョンごとに、独自の発行者ポリシー ファイルが割り当てられます。 たとえば、バージョン 2.0.2.222 から 2.0.3.000 へのリダイレクトと、バージョン 2.0.2.321 からバージョン 2.0.3.000 へのリダイレクトは、どちらも同じファイルになります。これは、バージョン 2.0 に関連付けられているためです。 ただし、バージョン 3.0.0.999 からバージョン 4.0.0.000 へのリダイレクトは、バージョン 3.0.999 のファイルに入ります。 .NET Framework の各メジャー バージョンには、独自の発行元ポリシー ファイルがあります。

アセンブリの発行元ポリシー ファイルが存在する場合、ランタイムはアセンブリのマニフェストとアプリ構成ファイルを確認した後、このファイルをチェックします。 ベンダーは、新しいアセンブリがリダイレクトされるアセンブリと下位互換性がある場合にのみ、発行元ポリシー ファイルを使用する必要があります。

アプリの発行元ポリシーをバイパスするには、「発行者ポリシーのバイパス」セクションで説明されているように、アプリ構成ファイルで設定を指定します。

アプリ レベルでバージョンをリダイレクトする

アプリ構成ファイルを使用してアプリのバインド動作を変更するには、いくつかの異なる手法があります。ファイル を手動で編集、自動バインド リダイレクト に依存、または発行元ポリシーの をバイパスバインド動作を指定できます。

アプリ構成ファイルを手動で編集する

アプリ構成ファイルを手動で編集して、アセンブリの問題を解決できます。 たとえば、ベンダーが発行元ポリシーを提供せずにアプリで使用するアセンブリの新しいバージョンをリリースする場合 (下位互換性が保証されないため)、次のようにアプリの構成ファイルにアセンブリ バインド情報を配置することで、新しいバージョンのアセンブリを使用するようにアプリに指示できます。

<dependentAssembly>
  <assemblyIdentity name="someAssembly"
    publicKeyToken="32ab4ba45e0a69a1"
    culture="en-us" />
  <bindingRedirect oldVersion="7.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>

自動バインド リダイレクトに依存する

.NET Framework 4.5.1 以降のバージョンを対象とするデスクトップ アプリを Visual Studio で作成すると、アプリは自動バインド リダイレクトを使用します。 つまり、2 つのコンポーネントが同じ厳密な名前付きアセンブリの異なるバージョンを参照している場合、ランタイムは出力アプリ構成 (app.config) ファイル内の新しいバージョンのアセンブリにバインド リダイレクトを自動的に追加します。 このリダイレクトは、それ以外の場合に行われる可能性があるアセンブリの統合をオーバーライドします。 ソース app.config ファイルは変更されません。 たとえば、アプリが帯域外の .NET Framework コンポーネントを直接参照しているのに、同じコンポーネントの古いバージョンを対象とするサード パーティ製ライブラリを使用しているとします。 アプリをコンパイルすると、出力アプリ構成ファイルが変更され、新しいバージョンのコンポーネントへのバインド リダイレクトが含まれます。

Web アプリを作成すると、バインドの競合に関するビルド警告が表示されます。その結果、必要なバインド リダイレクトをソース Web 構成ファイルに追加するオプションが表示されます。

ソース app.config ファイルにバインド リダイレクトを手動で追加すると、コンパイル時に、Visual Studio は追加したバインド リダイレクトに基づいてアセンブリの統合を試みます。 たとえば、アセンブリに対して次のバインド リダイレクトを挿入するとします。

<bindingRedirect oldVersion="3.0.0.0" newVersion="2.0.0.0" />

アプリ内の別のプロジェクトが同じアセンブリのバージョン 1.0.0.0 を参照している場合、自動バインド リダイレクトにより、次のエントリが出力 app.config ファイルに追加され、アプリがこのアセンブリのバージョン 2.0.0.0 で統合されます。

<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />

アプリが以前のバージョンの .NET Framework を対象とする場合は、自動バインド リダイレクトを有効にすることができます。 この既定の動作をオーバーライドするには、任意のアセンブリの app.config ファイルにバインド リダイレクト情報を指定するか、バインド リダイレクト機能をオフにします。 この機能のオンとオフを切り替える方法については、「方法: 自動バインド リダイレクトを有効または無効にする」を参照してください。

発行元ポリシーをバイパスする

必要に応じて、アプリ構成ファイルの発行元ポリシーをオーバーライドできます。 たとえば、下位互換性があると主張するアセンブリの新しいバージョンでも、アプリが壊れる可能性があります。 発行元ポリシーをバイパスする場合は、<publisherPolicy> 要素をアプリ構成ファイルの <dependentAssembly> 要素に追加し、apply 属性を noに設定します。この属性は、以前の yes 設定をオーバーライドします。

<publisherPolicy apply="no" />

ユーザーに対してアプリを実行し続けるために発行元ポリシーをバイパスしますが、アセンブリ ベンダーに問題を報告してください。 アセンブリにパブリッシャー ポリシー ファイルがある場合、ベンダーはアセンブリに下位互換性があり、クライアントが可能な限り新しいバージョンを使用できることを確認する必要があります。

別のコンポーネントで使用されるテスト、プラグイン、またはライブラリのバージョンをリダイレクトする

テストの場合は、.dll.config ファイルを生成する必要があります。 ほとんどの既存の単体テスト フレームワークでは、テストの読み込み時にこれらのファイルが優先されます。

プラグインは .dll.config ファイルを尊重するかもしれませんが、そうでない場合もあります。 リダイレクトの唯一の確実なメカニズムは、AppDomain が作成されるときに bindingRedirects を提供することです。

AssemblyResolve イベント ハンドラーでこの問題を解決しようとする場合がありますが、失敗した読み込みでのみこれらのハンドラーが呼び出されるため、これは機能しません。 アセンブリが別のアセンブリまたはホストによって読み込まれたか、GAC に存在していたために、アセンブリの読み込みが成功した場合、AssemblyResolve ハンドラーは呼び出されません。

マシン レベルでバージョンをリダイレクトする

コンピューター管理者が、コンピューター上のすべてのアプリで特定のバージョンのアセンブリを使用することを望む場合はまれです。 たとえば、特定のバージョンでセキュリティ ホールが修正される場合があります。 アセンブリがコンピューターの構成ファイル (machine.configと呼ばれる) でリダイレクトされた場合、そのマシン上で古いバージョンを使用するすべてのアプリが新しいバージョンを使用するように指示されます。 コンピューター構成ファイルは、アプリ構成ファイルと発行元ポリシー ファイルをオーバーライドします。 この machine.config ファイルは、32 ビット コンピューターの場合は %windir%\Microsoft.NET\Framework[version]\config\machine.config、64 ビット コンピューターの場合は %windir%\Microsoft.NET\Framework64[version]\config\machine.config にあります。

構成ファイルでアセンブリ バインドを指定する

同じ XML 形式を使用して、バインド リダイレクトをアプリ構成ファイル、コンピューター構成ファイル、または発行元ポリシー ファイルのいずれに含めるかを指定します。 あるアセンブリ バージョンを別のアセンブリ バージョンにリダイレクトするには、<bindingRedirect> 要素を使用します。 oldVersion 属性では、1 つのアセンブリ バージョンまたはバージョンの範囲を指定できます。 newVersion 属性では、1 つのバージョンを指定する必要があります。 たとえば、<bindingRedirect oldVersion="1.1.0.0-1.2.0.0" newVersion="2.0.0.0"/> では、1.1.0.0 から 1.2.0.0 の間のアセンブリ バージョンではなく、ランタイムでバージョン 2.0.0.0 を使用する必要があることを指定します。

次のコード例は、さまざまなバインド リダイレクト シナリオを示しています。 この例では、myAssemblyのバージョンの範囲のリダイレクトと、mySecondAssemblyの単一のバインド リダイレクトを指定します。 また、この例では、myThirdAssemblyのバインド リダイレクトをパブリッシャー ポリシー ファイルがオーバーライドしないことを指定します。

アセンブリをバインドするには、文字列 "urn:schemas-microsoft-com:asm.v1" に <assemblyBinding> タグの xmlns 属性を指定する必要があります。

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="myAssembly"
          publicKeyToken="32ab4ba45e0a69a1"
          culture="en-us" />
        <!-- Assembly versions can be redirected in app,
          publisher policy, or machine configuration files. -->
        <bindingRedirect oldVersion="1.0.0.0-2.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="mySecondAssembly"
          publicKeyToken="32ab4ba45e0a69a1"
          culture="en-us" />
             <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
      <assemblyIdentity name="myThirdAssembly"
        publicKeyToken="32ab4ba45e0a69a1"
        culture="en-us" />
        <!-- Publisher policy can be set only in the app
          configuration file. -->
        <publisherPolicy apply="no" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

アセンブリ バインドを特定のバージョンに制限する

アプリ構成ファイルの <assemblyBinding> 要素で appliesTo 属性を使用して、アセンブリ バインド参照を特定のバージョンの .NET Framework にリダイレクトできます。 この省略可能な属性は、.NET Framework のバージョン番号を使用して、適用されるバージョンを示します。 appliesTo 属性が指定されていない場合、<assemblyBinding> 要素は.NET Framework のすべてのバージョンに適用されます。

たとえば、.NET Framework 3.5 アセンブリのアセンブリ バインドをリダイレクトするには、アプリ構成ファイルに次の XML コードを含めます。

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"
    appliesTo="v3.5">
    <dependentAssembly>
      <!-- assembly information goes here -->
    </dependentAssembly>
  </assemblyBinding>
</runtime>

リダイレクト情報はバージョン順に入力する必要があります。 たとえば、.NET Framework 3.5 アセンブリのアセンブリ バインド リダイレクト情報を入力し、その後に .NET Framework 4.5 アセンブリを入力します。 最後に、appliesTo 属性を使用せず、すべてのバージョンの .NET Framework に適用される .NET Framework アセンブリ リダイレクトのアセンブリ バインディング リダイレクト情報を入力します。 リダイレクトで競合が発生した場合は、構成ファイル内の最初の一致するリダイレクト ステートメントが使用されます。

たとえば、1 つの参照を .NET Framework 3.5 アセンブリにリダイレクトし、別の参照を .NET Framework 4 アセンブリにリダイレクトするには、次の擬似コードに示すパターンを使用します。

<assemblyBinding xmlns="..." appliesTo="v3.5 ">
  <!--.NET Framework version 3.5 redirects here -->
</assemblyBinding>

<assemblyBinding xmlns="..." appliesTo="v4.0.30319">
  <!--.NET Framework version 4.0 redirects here -->
</assemblyBinding>

<assemblyBinding xmlns="...">
  <!-- redirects meant for all versions of the runtime -->
</assemblyBinding>

関連項目