web-dev-qa-db-ja.com

同じフォルダ内の同じアセンブリの異なるバージョンを使用する

以下の状況があります

プロジェクトA

 - Uses Castle Windsor v2.2
 - Uses Project B via WindsorContainer

プロジェクトB

 - Uses NHibernate
 - Uses Castle Windsor v2.1

プロジェクトAのbinフォルダーには、dll Castle.DynamicProxy2.dll v2.2とNHibernate dllがあります。問題は、NHibernateがCastle.DynamicProxy2.dll v2.1に依存していることです。この状況を解決するにはどうすればよいですか。

61
Hemanshu Bhojak

次の構成を使用して問題を解決しました。

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
            <dependentAssembly>
                <assemblyIdentity name="Castle.DynamicProxy2" publicKeyToken="407dd0808d44fbdc" />
                <codeBase version="2.1.0.0" href="v2.1\Castle.DynamicProxy2.dll" />
                <codeBase version="2.2.0.0" href="v2.2\Castle.DynamicProxy2.dll" />
            </dependentAssembly>
            <dependentAssembly>
                <assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" />
                <codeBase version="1.1.0.0" href="v2.1\Castle.Core.dll" />
                <codeBase version="1.2.0.0" href="v2.2\Castle.Core.dll" />
            </dependentAssembly>
        </assemblyBinding>
    </runtime>
</configuration>
90
Hemanshu Bhojak

彼が十分な注意を払っていないと見逃すかもしれないということは、非常に、非常に重要です。

CodeBaseバージョンタグで記述するアセンブリは、厳密な名前である必要があります。

次のリンクから: http://msdn.Microsoft.com/en-us/library/efs781xb.aspx

厳密な名前のないアセンブリの場合、バージョンは無視され、ローダーは<dependentAssembly>内の<codebase>の最初の外観を使用します。バインディングを別のアセンブリにリダイレクトするエントリがアプリケーション構成ファイルにある場合、アセンブリのバージョンがバインディング要求と一致しない場合でも、リダイレクトが優先されます。

1つの解決策(または回避策)は、ソフトウェアが必要なマシンのGlobal Assembly Cache(GAC)に両方のバージョンをインストールすることです実行し、厳密な名前を使用してアセンブリを参照します。これは、アセンブリに実際に厳密な名前があることを前提としています。

数人以上の開発者がいる場合、またはソリューションを多数のコンピューターに展開する場合(エンドユーザーアプリケーションとして)、GACへのインストールは苦痛になります。この場合、2つのバージョンのいずれかをそのバージョンを必要とするアセンブリにマージすることが唯一のオプションであると信じています(しかし間違っているかもしれません)。特定のケースでは、Castle.DynamicProxy2.dll v2.1をNHibernate.dllにマージする必要があります。

ILMerge というツールを使用して、アセンブリをマージできます。実行する必要があるコマンドは、次のようなものです(テストされていません):

ILMerge /t:library /internalize /out:Deploy/NHibernate.dll
    NHibernate.dll Castle.DynamicProxy2.dll

/internalizeスイッチは、出力アセンブリで2番目のアセンブリ(この場合は城)internalからのすべての型をマークするようにILMergeに指示します。これがないと、新しいNHibernate.dllCastle.DynamicProxy2.dll v2.2のシェルフバージョンの両方を参照するプロジェクトをコンパイルしようとすると、まったく同じ名前のクラスが含まれるため、コンパイルエラーが発生する可能性があります。

9

同じアセンブリの2つのバージョンを同じコンテキストにロードしたくないため、Hemanshu Bhojakのソリューションは良いとは思いません。この記事ではその理由を説明します。

http://msdn.Microsoft.com/en-us/library/dd153782.aspx#avoid_loading_multiple_versions

2
Jonathan Parker