前陣子介紹過在Vistual Studio 2010專案中輕鬆加入程式庫的優雅做法--NuGet,這幾天終於有機會體驗了NuGet程式包(NuGet Package)的製作過程與實際應用。

工作專案中有個電子表單平台,我發展了一些元件可在ASP.NET中加入表單傳簽功能,但實際運作時除了DLL外,還需要配套的jpg, png, js, css等,web.config也得加入幾個appSetting設定,表單ASPX才能順利執行。過去為了讓同事能在個人的專案中加入表單元件及相關檔案,我的做法是包一個小型的ASP.NET Web Site專案,其中執行表單最基本的元件及檔案需求。同事可以以這個範本專案當成湯底再開始加料寫程式;或是將範本專案檔案跟原有專案倒在一起煮成一大鍋。(會想出這比喻應該是餓了的關係) 但要在原有專案的web.config加設定,則需要額外文件說明需加入的項目。

見識過上流社會的料理,就不該繼續茹毛飲血囉! 於是,趁著這個案例,我試做了第一枚NuGet程式包。

NuGet提供了nuget.exe命令列工具,透過.spec XML檔案設定程式包識別資訊,配合在同目錄下建立特定資料夾: content(放置要部署到專案根目錄下的資料夾結構及各種檔案)、lib(放置要部署到bin下的DLL檔案,可為不同.NET Runtime版本提供專屬DLL)、tools(安裝過程要執行的額外程序及用來做進階設定的工具程式),接著執行nuget pack MyPackage.nuspec就可產出MyPackage.nupack。關於建立程式包的方法,NuGet網站上有很詳細的介紹,動手前值得一讀。

除了使用nuget.exe命令列工具,還有個NuGet Package Explorer提供圖形化操作建立程式包,雖然目前仍只在Beta 2階段,不少功能還很陽春(甚至有些簡陋,例如,尚不支援一次加入整個資料夾),但能完全透過GUI點選輸入就做出程式包已經挺好的,我還是決定靠它來完成NuGet程式包處女航。

從NuGet專案的下載區可以取得NuGet Package Explorer的ClickOnce安裝程式,安裝好選取File/New就可以開紿編輯NuGet程式包。使用Edit/Edit Package Metadata輸入程式包相關設定(如下圖),其中識別碼(Id)與版本(Version)是日後移除、自動更新程式包的依據,要留意管控、Authors指的是程式庫專案的開發者、Owners則是程式包的製作人、Icon Url可以指向一個32x32的PNG檔案(支援透明背景)將來會顯示在NuGet Package Manager上、Project Url則指向程式庫專案入口網站、Tag用來協助分類及檢索。有些程式包需要依靠其他程式包才能運作,在Depdencies裡輸入相依的程式包Id及Version,NuGet Package Manager會一併檢查相依關係並自動下載安裝。

輸入相關資訊後,右方的Package contents是個資料夾與檔案的樹狀圖,按下右鍵可建立資料夾及新增檔案,但依實際操作經驗,用拖拉方式新增檔案會比按右鍵選檔來得直覺方便,只是無法一次拖入整個資料夾有點可惜,不過操作起來會更順暢。content下的資料夾結構及檔案未來會被複製到專案根目錄下,所以照著原本在Web Application下的配置,一一建立資料夾並放入檔案即可。

2014-06-10更新: NuGet Package Explorer已成為獨立CodePlex專案,感謝Alex補充

另外,由於我們要在web.config中新增appSetting。NuGet提供的做法是在content中放入web.config.transform,其中只需包含要新增的XML節點,實際安裝時,NuGet會將web.config.transform的內容合併到專案原有web.config中。移除程式包時,這些設定也會從web.config中自動移除。(但合併新增的設定若事後修改過,則不會被移除)

<configuration>
    <appSettings>
        <add key="LogFilePath" value="c:\temp\AfaLog"/>
        <add key="WorkflowDBName" value="AFA"/>
    </appSettings>
</configuration>

安排妥當,按下File/Save,就可以得到MyPackage1.0.nupkg。但,檔案要放在哪裡給VS2010下載?只限公司內部使用的程式包,總不好上傳到開放社群共用的NuGet Gallery平台吧? 針對這類需求,NuGet Package Manager支援自訂程式包來源。

先選定一個網路資料夾,將MyPackage1.0.nupkg擺進去,然後由VS2010選單Tools/Library Package Manager/Package Manager Settings或Add Library Package Reference對話框的Settings鈕,可進入程式包來源設定畫面,在其中輸入來源名稱、UNC路徑,即可新增程式包來源。

在Add Library Package Reference畫面的Online頁籤下,可看到剛才新增的自訂程式包來源,選取MyPackge按下【Install】,NuGet就會將剛才content下的資料檔案結構複製到網站目錄下,web.config中也會新增前述的兩筆appSetting,三兩下就完成程式庫的安裝囉!

最後測試更新功能。在NuGet Package Explorer中將Version改為1.1,重新產生MyPackage1.1.nupkg,放進先前的網路磁碟中,透過Updates頁籤,果然出現了更新選項。按下【Update】鈕,NuGet會移除1.0版的MyPackage,移除網站目錄下程式包所新增的檔案,並刪除web.config中的兩筆appSetting設定,之後會安裝MyPackage 1.1版,完成自動更新版本的動作。
(注意: 如果更動過NuGet程式包所安裝的js, css, cs等檔案內容或修改web.config新增的設定,NuGet在移除程式包時透過比對,會保留被更動過的檔案或設定不刪除,以免誤刪變更內容,但再次安裝時NuGet程式包時亦會略過這些已存在的檔案,可能衍生一些問題,這點未來會另做討論)


Comments

# by 路人假

又來個新技術啦... 還請過目下面所列的文章... Windows编程革命简史 http://coolshell.cn/articles/3008.html#more-3008 看完之後有沒有一股蛋蛋的憂傷...

# by Alex

Nuget Package Explorer 目前已經被 獨立出來放到 http://http://npe.codeplex.com/

# by Jeffrey

to Alex, 感謝補充,已加入本文。

# by 小馬

請問黑哥, 若公司內部使用,若有更新版的組件被放上去,使用者是否會在通知中顯示資訊呢?

# by Jeffrey

to 小馬,不會主動通知,手動開啟NuGet管理員的Updates頁籤,NuGet會檢查組件是否有新版,若有新版可直接按鈕更新,跟由NuGet公開伺服器下載的組件行為相同。

# by Alex

看時光飛逝.... nuget package explorer 又換載點了 https://github.com/NuGetPackageExplorer/NuGetPackageExplorer 改由市集或是 powell shell 下載安裝

Post a comment