web-dev-qa-db-ja.com

同じアセンブリの異なるバージョンを参照する

AがアセンブリB1.1とCを参照し、CがB 1.2を参照している場合、アセンブリの競合をどのように回避しますか?

Cの参照はカプセル化されて問題が発生しないと思いましたが、すべてのdllが問題が発生するbinにコピーされているようです。

これを回避する2つの方法は、GACまたはアセンブリバインディングを使用することです。 GACは、私にとって最善のアプローチではないようです。dllがそこにあると想定するのは好きではないので、ソリューションのlibディレクトリからdllを参照することを好みます。

アセンブリバインディングは私には堅牢ではないように見えますが、アセンブリの一方のバージョンにもう一方のバージョンにはない機能がある場合、これによって問題が発生することはありませんか?


私の場合、サードパーティのdllを使用しているため、自分で使用しているよりも古いバージョンのnHibernateを使用しています。

34
Dan

過去にGACを使用して同じ結果を達成しましたが、複数のバージョンを参照する必要がある理由を疑問視し、可能であればそれを回避するようにしてください。あなたがそれをしなければならないなら、 バインディングリダイレクト があなたの場合に役立つかもしれません。

また、 this をもう読んだことがありますか?

9
Kilhoffer

これを行う方法はほとんど知られていないようですが、externキーワードを使用することです。

から C#リファレンス

同じ完全修飾型名を持つ2つのアセンブリを参照するには、次のようにコマンドプロンプトでエイリアスを指定する必要があります。

/r:GridV1=grid.dll

/r:GridV2=grid20.dll

これにより、外部エイリアスGridV1およびGridV2が作成されます。プログラム内からこれらのエイリアスを使用するには、externキーワードを使用してそれらを参照します。例えば:

externエイリアスGridV1;

externエイリアスGridV2;

各externエイリアス宣言は、グローバル名前空間に類似する(ただし、その中には存在しない)追加のルートレベル名前空間を導入します。したがって、各アセンブリの型は、適切な名前空間エイリアスにルート化された完全修飾名を使用することで、あいまいさなく参照できます。

前の例では、GridV1 :: Gridはgrid.dllからのグリッドコントロールであり、GridV2 :: Gridはgrid20.dllからのグリッドコントロールです。

7
Peter Kelly

アセンブリの複数のバージョンをサポートする必要があり、次の解決策を見つけました。

  <runtime>
    <assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="MyAssembly" publicKeyToken="..." />
        <codeBase version="1.1.0.0" href="MyAssembly_v1.1.0.0.dll"/>
        <codeBase version="2.0.0.0" href="MyAssembly_v2.0.0.0.dll"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
3
burton

bindingRedirect要素 を構成ファイルに追加して、実行時に使用するアセンブリのバージョンを指定できます。

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="myAssembly"
                              publicKeyToken="32ab4ba45e0a69a1"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>
1
Joe

.NETランタイムは、同じアセンブリの複数のバージョンを同時にロードすることができます。ただし、このワームの缶を開く場合は、アセンブリにstronlyという名前を付け、Major.Minor。*命名スキームを使用して名前の競合を回避することを強くお勧めします。

GACを使用する(または使用しない)ための万能のアプローチを考えるべきではないと思います。 DLLの将来のバージョンで公開された新しい機能を自動的に使用したい場合、GACは非常に便利です。もちろん、この祝福には、新しいバージョンが期待どおりに機能しない可能性があるという代償が伴います:)。それはすべて、何が最も実用的であり、GACに公開されるものをどの程度制御できるかという問題です。

よろしく、-アラン。

1
AlanR