【茶包射手日記】MSBuild.ILMerge.Task發生型別重複錯誤

讀者Peter回饋一起MSBuild.ILMerge.Task合併錯誤案例:專案引用Manatee.Trello.WebApi套件,其依賴Microsoft.AspNet.WebApi.Client.5.2.3(System.Net.Http.Formatting.dll)及Microsoft.AspNet.WebApi.Core.5.2.3(System.Web.Http.dll),合併時出現錯誤:ILMerge.Merge: ERROR!!: Duplicate type 'System.Net.Http.HttpRequestMessageExtensions' found in assembly 'System.Web.Http'. Do you want to use the /alllowDup option?

一般來說,Namespace加上型別名稱應該是唯一的,撞名實屬罕見,引發我的好奇想一探究竟。試開一個新專案引用Manatee.Trello.WebApi與MSBuild.ILMerge.Task,合併組件時也拋出相同錯誤訊息。能重現錯誤一切好辦,著手展開調查。

手動以ILMerge.exe合併組件也出現相同錯誤,依訊息補上/allowDup參數便可避免錯誤。

依此研判,問題出在要合併的組件內含完全相同的類別名稱!使用Telerik JustDecompile分析,果真在System.Net.Http.Formatting.dll與System.Web.Http.dll發現兩個同名型別-HttpRequestMessageExtensions與MediaTypeFormatterExtensions:

 

原來這兩個型別是宣告擴充方法(Extension Method)的靜態型別,應用時完全不會用到型別名稱,故在不同DLL重複出現也無妨;一旦具有同名型別的組件要合併,名稱重複問題才會浮上檯面。

由此可知,執行ILMerge.exe時加上allowDup參數即可解決問題,但一直沒找到文件示範如何為MSBuild.ILMerge.Task加上allowDup參數。歷經一番研究,我發現合併作業的核心邏輯寫在MSBuild.ILMerge.Task.dll,反組譯發現其中有實作AllowDuplicateType參數,但似乎只能透過targets設定檔指定。

在packages\MSBuild.ILMerge.Task.1.0.2\build\MSBuild.ILMerge.Task.targets找到<MSBuild.ILMerge.Task>,加上AllowDuplicateType = "*"(或是明確列出已知的重複名稱型別,如AllowDuplicateType = "HttpRequestMessageExtensions,MediaTypeFormatterExtensions"),等同為ILMerge.exe加上/allowDup參數。(註:此種參數修改做法影響範圍將涵蓋整個解決方案)

修改後重新編譯,組件成功合併,問題排除,收工~

歡迎推文分享:
Published 17 May 2016 11:08 PM 由 Jeffrey
Views: 3,014



意見

# Peter said on 17 May, 2016 11:41 AM

我媽問我為什麼跪在電腦前,真是太神了。

真的太感謝黑大了,大大學了一課。

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<May 2016>
SunMonTueWedThuFriSat
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234
 
RSS
創用 CC 授權條款
【廣告】
twMVC
最新回應

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication