不管多麼努力,Microsoft 也沒辦法提供開發人員所須要的每個庫。 雖然 Microsoft 在全球的員工人數接近 90,000,但全球的開發人員數以百萬計。 期望 Microsoft 知足每個人的需求是不現實的,也不可想像。 所以,開發人員一般得本身動手解決問題,他們目前已經編寫了成千上萬的實用庫,並將其發佈到 Web 上。shell 如何共享如此多的庫是一個使人頭痛的問題。 共享和重用代碼是一個很大的挑戰。 不相信? 請隨便走進一間中型或大型工做室,問問他們有多少日誌記錄庫。 訪問多家公司後,您將發現他們擁有比例很是高的內部日誌記錄庫,而這些庫中有一些很是不錯,例如,Log4Net、NLog 和 Error Logging Modules and Handlers(即 ELMAH)。緩存 當一位開發人員開始新項目時,他將面對一張空白的畫布。 他如何去發現這些有用的庫? 如何將庫集成到當前項目中並管理庫的依賴項和更新呢?安全 ELMAH 就是一個很是有用的庫,是由開發人員本身編寫的。 ELMAH 可以在出現異常時記錄 Web 應用程序中全部未經處理的異常以及全部請求信息,例如,標頭、服務器變量等。 假設您剛剛據說 ELMAH 並但願在下一個項目中使用它。服務器 您可能會採起下列步驟:網絡
真是很麻煩! 如今,假設您必須爲 10 至 15 個依賴項執行這些操做。 當您的應用程序要發佈新版本時,您須要花費大量時間爲應用程序的依賴項搜索更新。app 「非我發明」(NIH) 過去經常遭到非議,而在如今聽起來倒是不錯的主意。ide NuGet 應運而生NuGet 是一種 Visual Studio 擴展,它可以簡化在 Visual Studio 項目中添加、更新和刪除庫(部署爲程序包)的操做。 NuGet 程序包是打包成一個文件的文件集,擴展名是 . nupkg,使用開放打包約定 (OPC) 格式。工具 OPC 僅僅是具備某些元數據的 zip 文件的首字母縮寫詞。 事實上,您可能早已熟悉 OPC,由於 Word 和 Excel 文檔正是使用此格式。 若是您取一個 .docx 文件並將文件擴展名改成 .zip,您實際能夠打開它並瀏覽裏面的內容。 . nupkg 文件一樣如此。測試 NuGet 產品一樣隨附可以輕鬆建立和發佈程序包的實用工具。 如今,我先重點介紹如何使用 NuGet 發現和安裝程序包。 以後,我將講述如何建立和發佈程序包。 安裝 NuGet要安裝 NuGet,從「Tools」(工具)|「Extension Manager」(擴展管理器)菜單選項啓動 Visual Studio Extension Manager。 單擊「Online Gallery」(聯機庫)選項卡查看可用的 Visual Studio 擴展名,如圖 1 中所示。 如您所見,NuGet 位於第一個屏幕,是排名最高的程序包。 若是狀況不是如此,您可使用右上角的搜索框找到它。 單擊「Download」(下載)按鈕安裝 NuGet。 若是您已經安裝了 ASP.NET MVC 3,則您已經安裝 NuGet。 ASP.NET MVC 3 包含 NuGet,而且 Microsoft 計劃在下一版本的 Visual Studio 中包含 NuGet。 安裝程序包咱們啓動用戶友好的 NuGet 對話框以安裝程序包。 NuGet 一樣內置基於 Windows PowerShell 的控制檯,此控制檯面向高級用戶(將在下文說起)。 要啓動 NuGet,請右鍵單擊項目的引用節點,而後選擇「Manage NuGet Packages」(管理 NuGet 程序包)選項(NuGet 1.4 以前的該選項具備不一樣的標籤)。 這將啓動「Manage NuGet Packages」(管理 NuGet 程序包)對話框,如圖 2 中所示。 請確保選中「Online」(聯機)選項卡,並在右上角輸入搜索詞(例如,搜索來自 StackOverflow.com 的實用庫 MiniProfiler)。 找到程序包後,單擊「Install」(安裝)按鈕安裝該程序包。 NuGet 隨後下載該程序包和它的依賴項,並將任何須要更改應用到程序包指定的項目中。 NuGet 執行下列步驟安裝程序包:
當 NuGet 執行全部這些步驟後,庫將準備就緒。 不少程序包使用 WebActivator 程序包自行激活,從而最小化安裝後所需的任何配置。 您能夠卸載程序包,這將使項目回到安裝程序包以前的狀態。 更新程序包在《軟件工程的事實和謬誤》(Addison-Wesley Professional,2002 年)一書中,Robert L. Glass 說:「維護工做一般約佔軟件成本的 40-80%(平均是 60%)。 所以,維護多是軟件生命週期中最重要的階段。」 安裝程序包僅僅是故事的開始。 在從此維護這些庫時,您必須及時更新應用程序,爲庫安裝最新的 Bug 修補程序。 這須要您回答一個問題:「此項目中的哪些依賴項有可用的最新更新?」 如前所述,回答此問題一直是一項耗時的工做。 然而,有了 NuGet,您只需啓動對話框並單擊「Updates」(更新)選項卡便可看到有可用更新的程序包列表,如圖 3 所示。 單擊「Update」(更新)按鈕可將程序包更新到最新版本。 更新命令卸載舊程序包,而後安裝新程序包,確保全部依賴項都根據須要獲得更新。 NuGet 在程序包管理器控制檯中提供便於控制更新的命令,例如,用以更新解決方案中的全部程序包或執行「安全」更新。 面向高級用戶的 NuGet雖然我對美觀的 GUI 對話框很是癡迷,但我知道不少開發人員很是鄙視像我同樣的鼠標操做者。 這些開發人員將命令行 shell 視做 UI,他們更願意經過這些 shell 組成命令集。 NuGet 可以知足這種需求,它提供基於 Windows PowerShell 的控制檯窗口(稱做程序包管理器控制檯)以及一組 Windows PowerShell 命令與 NuGet 進行交互。 Windows PowerShell 是基於 .NET 的腳本語言和命令行 shell,很是適合組成命令集,並可以處理對象。 要啓動程序包管理器控制檯,請導航至「Tools」(工具)|「Library Package Manager」(庫程序包管理器)|「Package Manager Console」(程序包管理器控制檯)菜單選項。 列出和安裝程序包要列出和搜索程序包,請使用 Get-Package 命令。 默認狀況下,該命令列出當前項目中的已安裝程序包。 您能夠經過指定 ListAvailable 標記和 Filter 標記聯機搜索程序包。 下列命令行搜索全部包含「MVC」的程序包: Get-Package -ListAvailable -Filter Mvc 找到要安裝的程序包後,使用 Install-Package 命令。 例如,要將 ELMAH 安裝到當前項目: Install-Package Elmah 因爲 Windows PowerShell 是動態語言,它可以提供 Tab 擴展功能,從而幫助您正確輸入命令行參數。 Tab 擴展等同於 C# 的 IntelliSense,但與基於編譯時信息的 IntelliSense 不一樣,您能夠在運行時填充 Tab 擴展。 例如,若是您輸入 Install-Package Mvc{tab},您將看見一個列表,包含可能來自程序包源的程序包名稱,如圖 4 所示。 更新程序包程序包管理器控制檯還包含一個命令,與對話框相比,它提供更多的更新控制。 例如,無需參數便可調用此命令以更新解決方案的每一個項目中的各程序包: Update-Package 此命令嘗試將每一個程序包都更新到最新版本。 所以,若是您有 1.0 版本的程序包,而 1.1 和 2.0 版本在該程序包源中可用,則該命令將此程序包更新至最新的 2.0 版本。 若是任何程序包包含重大改變,這會是一項很是重大的操做。 在多數狀況下,您僅但願將各程序包更新至最新的修補程序版本。 這叫「安全」更新,前提是具備較大內部版本號或修訂號(但具備相同的主版本號和次版本號)的程序包可以向後兼容。 僅添加 Safe 標記以執行安全更新,例如: Update-Package -Safe 在這種狀況下,若是您安裝了 1.0.0 版本的程序包,而 1.0.1 和 1.1 版本在該程序包源中可用,則該程序包將安全地升級至 1.0.1 而非 1.1。 Update-Package 命令還提供更精細的控制,例如,將程序包更新至特定版本而非最新版本。 用新命令擴展 Visual Studio雖然使用 Windows PowerShell 安裝程序包的功能很不錯,但這不是咱們選擇 Windows PowerShell 的最主要緣由。 最主要緣由之一是程序包可以將新命令添加至程序包管理器控制檯。 這些命令可以與 Visual Studio DTE 交互以執行各類任務。 例如,安裝 MvcScaffolding 程序包時,它會將新 Scaffold Controller 命令添加至控制檯。 給定一個 Entity Framework (EF) Code First 對象,此命令生成一個控制器、控制器操做,以及 EF 對象的基本建立、讀取、更新和刪除 (CRUD) 操做對應的視圖,如圖 5 所示。 您的組織中的 NuGet因爲用戶僅關注 NuGet 如何簡化與公共開發人員社區共享庫,用戶一般很容易忽視 NuGet 在企業中的做用。 畢竟,企業也沒有特殊手段可以避免整個社區所面臨的代碼共享難題。 隨着公司的成長,平均信息量也在增長。 在同一間公司,不一樣的組使用各自專有版本的公司「標準」庫。 有些組可能會徹底無視這些庫,而是從頭本身編寫。 問題每每不在於庫自己,而在於與其餘團隊共享這些庫並通知他們更改時的麻煩。 聽起來是否是很熟悉? 程序包來源至此,我已講完如何安裝程序包,但還沒有回答這樣一個明顯的問題:這些程序包在哪? 它們位於 nuget.org 的官方 NuGet 程序包庫中。 此庫公開了一個 OData 源:packages. nuget.org/v1/FeedService.svc。 OData 格式使 NuGet 客戶端可以在客戶端上生成搜索程序包源的特定查詢,可是會在服務器上執行這些查詢。 要向 NuGet 添加更多程序包源,請導航至「Tools」(工具)|「Library Package Manager」(庫程序包管理器)|「Package Manager Settings」(程序包管理器設置)菜單選項,單擊「Package Sources」(程序包源)節點,如圖 6 所示。 默認的程序包源位於 Web 上的 OData 端點,但示例屏幕快照一樣將本地文件夾顯示爲程序包源。 NuGet 將文件夾(不管位於本地仍是網絡共享位置)視爲程序包源,並在「Online」(聯機)窗格中列出文件夾中的每一個程序包。 這樣一來,只需將代碼放入一個文件夾便可與他人共享,而且在測試您本身建立的程序包時一樣有用。 託管您本身的 NuGet 服務器除了在網絡共享上託管程序包以外,您還能夠將網站設置爲程序包源,使用網站與組織中的其餘人共享程序包。 若是有不少任務,還有一個程序包能夠在此處幫到您。 首先,在 Visual Studio 中建立一個空的 ASP.NET Web 應用程序(面向 ASP.NET 4)。 使用 NuGet 安裝程序包 NuGet.Server。 此程序包將簡單的 OData 端點添加到空 Web 應用程序中。 接着,將程序包文件添加到 Web 應用程序的 Packages 文件夾,以便發佈它們並部署網站。 有關如何設置的詳細信息,請參閱 NuGet 的文檔站點 bit.ly/jirmLO。 若是您但願部署相似 nuget.org 的完整庫體驗,NuGet 庫代碼還可經過 nugetgallery.codeplex.com 項目做爲開放源項目提供。 經過託管專用 NuGet 服務器或庫實施,您能夠方便地在公司內部共享專有代碼,無需公開發布。 建立程序包NuGet 發揮做用的前提是有程序包可供安裝。 NuGet 中的有用程序包越多,NuGet 對每一位開發人員的價值越大。 這就是 NuGet 團隊不辭勞苦儘量建立使用方便的程序包的緣由。 雖然程序包的建立不難,但 NuGet 團隊一直在對其功能進行投資,以使之更加簡單。 他們已開發若干用於建立 NuGet 程序包的工具。 例如,Package Explorer 是 NuGet 團隊的開發人員編寫的一個 ClickOnce 應用程序,使用者能夠憑藉它在建立或測試程序包時進行可視化操做。 您能夠在 npe.codeplex.com 下載該應用程序。 NuGet.exe因爲大多數程序包做者都但願將程序包的建立集成到生成流程,讓咱們看看使用 NuGet 命令行實用工具的其餘方法。 您僅需從 bit.ly/gmw54b 下載一次該實用工具。 下載 NuGet.exe 後,請確保將其放入已添加至 PATH 環境變量的文件夾。 我針對此類實用工具建立了一個名爲「utils」的文件夾。 我之因此說只需下載 NuGet.exe once 一次(每臺計算機一次),是由於它是自行更新的可執行程序。 若是出現更新的版本,僅需運行如下命令,NuGet 即會聯機檢查並自行更新至最新版本: nuget update –self 該命令行工具可以查詢相似程序包管理器控制檯的聯機源。 例如,要搜索帶「MVC」的全部程序包,可以使用如下命令: nuget list Mvc NuGet.exe 甚至可以下載程序包和依賴項並解壓縮它們,但它不能將項目修改成引用已下載的程序包程序集或運行程序包中包含的任何 Windows PowerShell 腳本。 從項目建立程序包程序包在 90% 的狀況下僅包含一個程序集(據本人統計)。 此部分講述使用 NuGet.exe 針對項目文件(例如,.csproj 或 .vbproj 文件)建立上述程序包的簡單流程。 有關建立較複雜程序包(例如,針對不一樣 .NET Framework 版本的單個程序包)的詳細信息,請參閱 docs.nuget.org 的 NuGet 文檔網站。 建立程序包的基本步驟:
建立類庫項目。要共享程序集,首先要建立類庫項目。 NuGet 能夠壓縮多個項目類型,但共享代碼時最多見的狀況是使用類庫。 建立程序包後,務必打開 AssemblyInfo.cs 文件以更新程序集的元數據。 建立 NuSpec 清單。NuSpec 文件是程序包清單,包含與程序包有關的重要元數據(例如,做者、描述和程序包依賴項)。 本身動手建立 NuSpec 格式很簡單,但使用 spec 命令建立此文件更加方便。 確保在項目文件所在目錄中運行命令: nuget spec 在此特定狀況下,因爲 spec 命令從項目文件生成 NuSpec,它會包含某些元數據的佔位符,如圖 7 中所示。 圖 7:生成的 NuSpec 文件 <?xml version="1.0"?> <package xmlns= "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> <metadata> <id>$id$</id> <version>$version$</version> <title>$title$</title> <authors>$author$</authors> <owners>$author$</owners> <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl> <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl> <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>$description$</description> <copyright>Copyright 2011</copyright> <tags>Tag1 Tag2</tags> </metadata> </package>
請勿編輯包含佔位符的字段,但應在其餘字段(例如,licenseUrl、projectUrl、iconUrl 和 tags)中填入正確的值。 更新項目的程序集元數據。每一個程序集都有與其關聯的元數據。 NuGet 可以讀取這些程序集元數據並在建立程序包時將其合併到 NuSpec 清單,從而確保了此信息始終在您的程序包和程序集中保持同步。 如此前所述,此信息一般位於名爲 AssemblyInfo.cs 的文件中。 圖 8 中的表顯示了程序集元數據和 NuSpec 佔位符值之間的對應關係。 圖 8:映射到 NuSpec 的程序集元數據
與其餘字段不一樣,$id$ 字段並不是從程序集屬性提取,而是設置爲程序集名稱。 建立程序包。在項目文件和 NuSpec 文件所在目錄中,運行如下命令以建立程序包: nuget pack ProjectName.csproj 若是同一個目錄中只有一個項目文件,則在運行命令時能夠省略項目文件名稱。 若是還沒有編譯項目,可先用 Build 標記編譯項目,而後壓縮它。 這將在運行 pack 命令以前編譯項目: nuget pack ProjectName.csproj -Build 此命令將生成名爲 ProjectName.{version}. nupkg 的文件,其中,{version} 的值與 AssemblyVersionAttribute 中指定的值相同。 例如,若是版本是 1.0.0,您的程序包將命名爲 ProjectName.1.0.0. nupkg。 您能夠在操做後使用 Package Explorer 檢查程序包,以確保建立正確。 爲了方便開發人員安裝您的程序包,請考慮使用 Symbols 標記建立帶調試器符號的程序包: nuget pack ProjectName.csproj -Build -Symbols 除了主程序包以外,此命令還建立符號程序包。 這使安裝您的程序包的其餘人在調試其應用程序時可以單步執行程序包代碼。 發佈程序包建立程序包後,您可能但願與全世界共享。 NuGet.exe 專門針對此目的提供一條發佈命令。 發佈以前,您須要在 nuget.org 上建立一個賬戶。 註冊賬戶後,單擊指向您的賬戶的連接以查看您的訪問密鑰。 此密鑰很是重要,由於向 nuget.exe 命令標識庫,而且是可撤消的密碼。 一旦擁有本身的密鑰後,請使用如下命令將其存儲在安全的位置: nuget setApiKey b688a925-0956-40a0-8327-ff2251cf5f9a 存儲密鑰後,使用 push 命令將您的程序包發佈到庫: nuget push ProjectName.1.0.0. nupkg 在庫上載程序包以前,該命令將驗證庫的 API 密鑰。 若是您建立了前述符號程序包,則應在對程序包執行 push 命令時指定 Symbols 標記: nuget push ProjectName.1.0.0. nupkg -Symbols 確保指定主程序包名稱而非符號程序包名稱。 依照慣例,此命令查找特定的符號程序包。 此命令將主程序包推送到 NuGet 庫,並將符號程序包推送到合做夥伴的 symbolsource.org 存儲庫。 後序在本文中,我演示了 NuGet 如何從 NuGet 庫提取有用的庫以助推新項目開發的啓動。 在企業內部,NuGet 可用於在組織中的不一樣開發人員之間共享代碼。 可是我須要指出,你們對 NuGet 存在一種固有的誤解:NuGet 僅適合 Web 開發人員。 該誤解可能源於它隨附在 ASP.NET MVC 3 版本中,但這種觀點是錯誤的。 NuGet 並不是僅針對 Web 開發人員,而是全部開發人員。 NuGet 支持 Windows Phone、Silverlight、Windows Presentation Foundation 以及其餘項目類型,並將在從此支持新的項目類型。 NuGet 是社區驅動的開放源碼項目,經過 Apache 2 許可註冊。 該項目屬於 Outercurve Foundation,但已集成到 Microsoft 的產品,而且若干 Microsoft 開發人員已成爲它的核心參與者。 若但願幫助 NuGet 的開發,請訪問 nuget.codeplex.com 以瞭解如何參與其中以及如何對 NuGet 作出貢獻。 本文章僅對 NuGet 的功能進行了初步探討。 要了解更多信息,請訪問 docs. nuget.org 的 NuGet 文檔網站(開發團隊在對其進行精心維護,並接受對其文檔的貢獻)。 開發團隊積極參與 CodePlex 討論論壇中有關 NuGet 項目的討論,並歡迎您提出有關問題。 Phil Haack 是 Microsoft ASP.NET 團隊的高級項目經理,專一於爲開發人員建立優秀的產品。他參與 ASP.NET 不少領域的工做,他的主要項目是 ASP.NET MVC 和 NuGet 程序包管理器,這兩個產品均經過 OSS 許可證發佈。在工做之餘,他會在博客 (haacked.com) 上寫有關軟件的文章,並研究 Subtext 開放源碼博客引擎。 衷心感謝如下技術專家對本文的審閱: David Fowler |