2つのDLLが競合して、ビルドするソリューションが妨げられる可能性はありますか


9

特定のケースがありますが、一般的な状況について疑問に思いました。

2つのDLLをVisual C#プロジェクトへの参照として追加すると、ソリューションが構築されないように互いに衝突する可能性がありますか?これが事実である場合、これを軽減する可能な方法は何ですか。

回答:


13

これは非常に可能です。

異なるアセンブリ(またはプロジェクトと追加されたアセンブリ)で同じ名前空間と型名を定義した場合、これらの型のいずれかを使用しようとするコードとの競合が発生します。

参照と同様に、一意の名前空間があることを確認すると、この問題は発生しません。

別の可能性は、依存関係の異なるバージョンと関係があります-プロジェクトが(たとえば)バージョン1.2のログライブラリを使用しているが、追加されたアセンブリが同じアセンブリであるが異なるバージョン(たとえば1.3)とプロジェクトのいずれかに依存している場合または、追加されたアセンブリが特定のバージョンを使用するように構成/構築されている場合、競合が発生し、ビルドが失敗します。

これらの問題はどちらも、ここで説明するように、アセンブリエイリアスを使用して解決できます


これが本当かどうかは完全にはわかりません。CILを見ると、CLRは特定のアセンブリ内のシンボルを明示的に参照しており、各シンボルの前に[アセンブリ]表記があります。C#コンパイラがこの問題を強制している可能性もありますが、プラットフォームの制約ではないと思います。
Yam Marcovic

@Yam Marcovicコンパイラーは、特定のクラスでどの名前空間を使用しようとしているのかをどのように判断しますか?完全修飾クラス名の競合は間違いなくビルドを妨げます。
ジェレミー

C#コンパイラは、同じ名前のアセンブリを処理する場合(およびそれらに同じシンボルが定義されている可能性がある場合)に、アセンブリエイリアスのオプションを提供します。stackoverflow.com/questions/517058/…を
Yam Marcovic

@Yam-True、ただし、このフラグについて知って使用する必要があります。単にアセンブリを追加すると、ビルドが壊れます。
2010年

1
明らかに。それが彼が助けを求めてここに来る理由ですよね?プロジェクトやサードパーティのユーティリティに影響を与えることなく、よりクリーンなソリューションを提供するため、彼はこのフラグについて知り、それを使用したいと考えています。
Yam Marcovic

4

他の誰もこれについて言及していないので、あなたは尋ねました:

これを軽減するために可能な方法は何ですか

この場合のためのクリーンなソリューションがあり、制約はなく、迷惑な回避策はありません。アセンブリのエイリアスを定義して、コンパイラが適切な場所で参照するエイリアスを認識できるようにすることができます。

見てhttp://blogs.msdn.com/b/ansonh/archive/2006/09/27/774692.aspx


3

はい、これは非常に可能です。
たとえば、Lucene.Netの古いバージョンを使用するDLLへの参照を追加し、最新バージョンを含めたいとします。
externエイリアスを使用すると、この問題を解決できます。http://msdn.microsoft.com/en-us/library/ms173212.aspx


+1これは正解のようですが、「extern」エイリアスはどうですか。
Jalayn、2011年

1

アセンブリの厳密な名前が付けられていれば、アセンブリのさまざまなバージョンをグローバルアセンブリキャッシュにいくつでも置くことができます。これは、さまざまなアプリケーションでマシンのさまざまなバージョンのアセンブリを使用する場合に役立ちます。ただし、1つのアプリケーションで異なるバージョンのアセンブリを使用すると、問題が発生します。

両方のバージョンを同時に必要とする理由は何ですか?


1
まあ私は明示的に異なるバージョンを追加していません。基本的に私はWPFアプリを持っています。ここで、サードパーティの機能を追加するために、いくつかのDLLを追加しました。これらのDLLが競合している可能性があります。
Shamim Hafiz、2011

1
OK、次にこれらのサードパーティ関連のDLLをGACに追加しますか?それらについて読んだのは久しぶりですが、これで問題を解決できると思います。
Jalayn、2011年

ここでGACとはどういう意味ですか?
Shamim Hafiz、2011

1
グローバルアセンブリキャッシュ、msdn.microsoft.com
en

0

確かに。2つのオブジェクトを区別できない場合、「あいまいな参照」コンパイラエラーが発生する可能性があります。通常、コードでフルパスを指定でき、問題は発生しませんが、DLLが完全に同一である場合、2つのオブジェクトをどのように区別することもできません。Syaには2つのDLLがあります。

Fileクラスを含むSystem.IO

そして

Fileクラスを含むMyProject.IO

このようなものがあったら...

using System.IO;
using MyProject.IO;

...
private void foo()
{
    File f = new File();
}

...話しているファイルを判別する方法がないため、あいまいな参照があります。これはそれを修正します:

using System.IO;
using MyProject.IO;

...
private void foo()
{
    MyProject.IO.File f = new MyProject.IO.File();
}

修正が困難な唯一の方法は、両方のアセンブリで「ファイル」のパスが同じである場合ですが、2つのDLLが同じ名前空間構造を持つというまれな状況が必要になります。たとえば、(「。Netフレームワークの実際の開発者を除いて)プロジェクトに「システム」という名前を付ける人はいないため、上記の私の状況は決して起こりません。


人気のあるサードパーティのライブラリに基づいてソリューションを構築する場合、実際にはそれはよく起こります。例えば、Twitterのライブラリは、あなたのJSONのlibの古いバージョンに依存して
ホアンロング
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.