본문 바로가기
개발/.NET

어셈블리 병합 유틸리티

by 그저그런보통사람 2011. 2. 18.

다운로드 (아래 링크)

오픈소스를 이용하여 개발을 하다보면 가끔 동일한 어셈블리의 버전 문제로 
충돌이 일어나 머리를 지끈거리게 만든다.

예를 들어 NHibernate 3.0 에서 Linq를 지원하기 위해 Remotion.Data.Linq.dll 를 사용하는데 
이 때 사용하는 어셈블리 버전은 1.13.42.2 다.
그리고 여기에 유틸리티 어셈블리를 추가하는데 이 유틸리티 역시 Remotion.Data.Linq.dll를 사용한다.
문제는 이 유틸리티가 사용하는 버전은 1.13.52.2 로 이 두 어셈블리를 같은 프로젝트에서 사용하면
어느 한쪽에서 문제가 발생하는 것이다.

서로가 내가 쓰는 버전을 찾을 수 없다는 에러 메시지를 보게 될 것이다.
오픈소스다 보니 소스를 받아 참조 어셈블리를 변경하는 것도 하나의 방법이지만, 해당 어셈블리가 버전
을 업그레이드하면서 추가된 내용과 함께 삭제된 내용이 있을 수 있다. 게다가 어셈블리가 오픈소스가
아니라면??? 결국 둘 중에 하나는 못쓰게 되는 것이다.

고민 고민 하면서 구글링을 하다보니 눈에 번뜩이는 내용을 찾을 수 있었다.
외국 사이트의 질답인데 어셈블리에 다른 어셈블리를 포함시킬 수 없냐는 질문이었고, 그에 대한 답변이
ILMERGE 유틸리티를 이용하라는 것이었다.

ILMerge.... 이놈은 MS에서 제공하는 유틸리티로 설치를 마치면 c:\Program Files\Microfost\ILMerge 
폴더에 콘솔 실행파일만 존재한다. 사용법은 이외로 간단하다.

c:\> ilmerge.exe "out:(병합 후 내보낼 어셈블리명.확장자)" "타겟 어셈블리(위치포함)" "병합할 어셈블리(위치포함)"

a.dll 와 b.dll 이 있고 a에 b를 포함시키고 싶고 병합한 dll 이름을 merged.dll 로 하고 싶다면
ilmerge.exe out:merged.dll a.dll b.dll 이렇게 하면 된다.
고맙게도 병합 후 디버거 파일도 제공한다. (^-^)

병합 후 어셈블리 내부를 Reflector로 열어보면 병합 대상이 되는 모든 소스가 넘어간 것이 보인다
네임스페이스 부터 원본 고유의 구조가 그대로 넘어가는 것이다.
즉 병합할 때 고려해야 하는 것 한가지는 A(타겟) 와 B(병합어셈블리) 의 네임스페이스 구조 밑 클래스명
(만약 네임스페이스가 명시적으로 구분되어 있으면 클래스명은 고려대상에서 제외)이 동일한지 살필 필요가 있다.


덕분에 버전 문제로 인한 동시 사용 충돌의 문제에서 벗어날 수 있게 되었다.