두 개의 DLL이 충돌하여 솔루션 빌드를 방해 할 수 있습니까?


9

구체적인 사례가 있지만 일반적인 상황이 궁금합니다.

Visual C # 프로젝트에 대한 참조로 추가 될 때 두 개의 DLL이 서로 충돌하여 솔루션 빌드를 방지 할 수 있습니까? 이 경우이를 완화 할 수있는 방법은 무엇입니까?

답변:


13

이것은 매우 가능합니다.

다른 어셈블리 (또는 프로젝트 및 추가 된 어셈블리)에서 동일한 네임 스페이스 및 유형 이름을 정의한 경우 이러한 유형 중 하나를 사용하려고하는 코드와 충돌이 발생합니다.

고유 한 네임 스페이스가 있는지 확인하면 참조와 마찬가지로이 문제가 발생하지 않습니다.

또 다른 가능성은 다른 버전의 종속성과 관련이 있습니다. 프로젝트에서 버전 1.2의 로깅 라이브러리를 사용하지만 추가 된 어셈블리가 동일한 어셈블리에 있지만 다른 버전 (1.3)과 프로젝트 중 하나에 의존하는 경우 또는 추가 된 어셈블리가 특정 버전을 사용하도록 구성 / 빌드 된 경우 충돌이 발생하여 빌드가 실패합니다.

여기에 설명 된대로 어셈블리 별명을 사용하여이 문제를 해결할 수 있습니다 .


이것이 사실인지 완전히 확신하지는 못합니다. CIL을 보면 CLR은 특정 기호 내에서 각 기호 앞에 [조립품] 표기법이있는 기호를 명시 적으로 참조합니다. C # 컴파일러 가이 문제를 강제 할 수는 있지만 이것이 플랫폼 제약 조건이라고 생각하지 않습니다.
얌 마르코비치

@ Yam Marcovic 컴파일러는 특정 클래스에서 어떤 네임 스페이스를 사용하려고하는지 어떻게 알 수 있습니까? 정규화 된 클래스 이름 충돌로 인해 빌드가 방지 될 것입니다.
Jeremy Jeremy

C # 컴파일러는 동일한 이름의 어셈블리를 처리 할 때 어셈블리 별칭을 정의 할 수있는 옵션을 제공합니다. 참조 stackoverflow.com/questions/517058/...
참마 Marcovic

@Yam-그러나이 플래그에 대해 알고 사용해야합니다. 어셈블리를 추가하면 빌드가 중단됩니다.
Oded

1
명백하게. 그래도 그가 여기 와서 도움을 받기 위해 온 이유는 무엇입니까? 그는이 플래그에 대해 알고 자신의 프로젝트 나 타사 유틸리티에 영향을주지 않으면 서보다 깨끗한 솔루션을 제공하기 때문에 사용하려고합니다.
얌 마르코비치

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 이것은 정답 인 것 같습니다. "외국인"별칭은 어떻습니까.
Jalayn

1

강력한 이름을 가진 경우 전역 어셈블리 캐시에 원하는만큼 다른 버전의 어셈블리 를 넣을 수 있습니다 . 다른 응용 프로그램이 다른 버전의 어셈블리를 기계적으로 사용하도록하려는 경우 도움이 될 수 있습니다. 그러나 하나의 응용 프로그램에서 다른 버전의 어셈블리를 사용하면 여전히 문제가 발생합니다.

두 버전을 동시에 필요로하는 이유는 무엇입니까?


1
글쎄, 나는 분명히 다른 버전을 추가하지 않습니다. 기본적으로 WPF 앱이 있습니다. 이제 타사 기능을 추가하기 위해 일부 DLL을 추가했으며 충돌 가능성이있는 DLL입니다.
Shamim Hafiz

1
그렇다면 이러한 타사 관련 DLL을 GAC에 추가 할 수 있습니까? 그 내용에 대해 읽은 지 오랜 시간이 지났지 만 이것이 문제를 해결할 수 있다고 생각합니다.
Jalayn

여기서 GAC의 의미는 무엇입니까?
Shamim Hafiz


0

확실 해요 두 개체를 구별 할 수없는 경우 "모호한 참조"컴파일러 오류가 발생할 수 있습니다. 일반적으로 코드에서 전체 경로를 지정할 수 있으며 문제가 발생하지 않지만 dll이 완전히 동일한 경우 두 객체를 구분할 수 없습니다. Sya에는 두 개의 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();
}

수정하기 어려운 유일한 방법은 "파일"의 경로가 두 어셈블리 모두에서 동일한 경우이지만 두 dll이 동일한 네임 스페이스 구조를 갖는 경우는 거의 없습니다. 예를 들어, 아무도 .Net 프레임 워크의 실제 개발자를 제외하고 프로젝트 "System"으로 이름을 지정하지 않기 때문에 위의 상황은 결코 일어나지 않을 것입니다.


인기있는 타사 라이브러리를 기반으로 솔루션을 구축하면 실제로 많은 일이 발생합니다. 예를 들어, 트위터 라이브러리는 이전 버전의 json lib에 의존 할 수 있습니다
Hoàng Long
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.