簡體   English   中英

如何使用共享程序集和項目?

[英]How do I work with shared assemblies and projects?

作為序言,我已經使用C#幾個月,但我完全不熟悉部署和匯編等概念。我的問題很多而且多種多樣,雖然我瘋狂地谷歌搜索並閱讀它們但無濟於事(我目前在我面前有Pro C#2008和.NET 3.5平台)。

我們有這個過程,它由三個組件組成:引擎,過濾器和過程邏輯。 我們非常喜歡這個過程,我們希望它能在其他項目中重復使用。 所以現在我開始探索超越一個解決方案,一個項目的空間。

這聽起來不錯嗎? 一個巨大的解決方

  • 進程A,exe
  • 進程B,exe
  • 進程C,exe
  • 過濾,DLL
  • 引擎,DLL

引擎是所有進程的共享代碼,所以我假設它可以是一個共享程序集? 如果共享程序集與使用它的項目在同一解決方案中,如果它應該在GAC中,它將如何被消耗? 我已經閱讀了一些關於post build事件的內容。 這是否意味着必須在每次構建時重新部署engine.dll?

此外,我們將過濾器與進程分離的原因(只有一個進程使用它)是因為我們可以獨立於進程部署過濾器,以便不需要更新進程可執行文件。 不管這是不是最好的做法,讓我們來看看吧。 這可能嗎? 我已經讀過程序集鏈接到其他程序集的特定版本,所以如果我只更新DLL,它實際上被認為是篡改。 如何在不更改EXE的情況下更新DLL? 這是出版商政策的用途嗎?

順便說一句,谷歌能夠或亞馬遜能夠擁有這些東西嗎? 我應該尋找什么? 我看到很多關於C#和.NET的書籍,但沒有關於部署,構建或測試或與語言本身無關的事情。

我同意Aequitarum的分析。 只需幾點:

引擎是所有進程的共享代碼,所以我假設它可以是一個共享程序集?

這看似合理。

如果共享程序集與使用它的項目在同一解決方案中,如果它應該在GAC中,它將如何被消耗?

魔法。

好吧,它不是魔術。 讓我們假設在您的解決方案中,您的流程項目引用了引擎項目 構建解決方案時,您將生成一個項目組件 ,該組件具有對引擎組件的引用。 然后,Visual Studio將各種文件復制到正確的目錄中。 執行流程程序集時,運行時加載程序知道在當前目錄中查找引擎程序集。 如果它在那里找不到它,它會在全局程序集緩存中查找。 (這是一個高度簡化的加載策略視圖;真正的策略比這復雜得多。)

GAC中的內容應該是真正的全球代碼; 您合理地期望使用大量不同項目的代碼。

這是否意味着必須在每次構建時重新部署engine.dll?

我不確定“重新部署”是什么意思。 就像我說的,如果你有一個項目到項目的引用,構建系統會自動將文件復制到正確的位置。

我們將過濾器與進程分離的原因(只有一個進程使用它)是為了使我們可以獨立於進程部署過濾器,以便不需要更新進程可執行文件

我懷疑這是否真的有價值。 場景一:沒有過濾器程序集,所有過濾器代碼都在project.exe中。 您希望更新過濾器代碼; 你更新project.exe。 場景二:filter.dll,project.exe。 您希望更新過濾器代碼; 你更新filter.dll。 情景二如何比情景一更便宜或更容易? 在這兩種情況下,您都在更新文件; 為什么文件名是什么?

但是,對於您的特定場景,它可能更便宜,更容易。 了解程序集的關鍵是程序集是可獨立版本化和可再發行代碼的最小單元。 如果你有兩件事,並且版本和彼此獨立發貨是有意義的,那么它們應該在不同的組件中; 如果這樣做沒有意義,那么它們應該在同一個組件中。

我已經讀過程序集鏈接到其他程序集的特定版本,所以如果我只更新DLL,它實際上被認為是篡改。 如何在不更改EXE的情況下更新DLL? 這是出版商政策的用途嗎?

組件可以被賦予“強名稱”。 當您將程序集命名為Foo.DLL,並且將Bar.EXE寫為“Bar.EXE依賴於Foo.DLL”時,運行時將加載恰好名為Foo.DLL的任何內容; 文件名不強。 如果惡意黑客將自己的Foo.DLL版本添加到客戶端計算機上,則加載程序將加載它。 一個強大的名字讓Bar.EXE說“由Bar Corporation編寫的Bar.exe版本1.2依賴於Foo公司編寫的Foo.DLL版本1.4”,所有的驗證都是針對與Foo Corp和Bar Corp.相關的加密密鑰完成的。

所以是的,可以將程序集配置為僅綁定來自特定公司的特定版本,以防止篡改。 你可以做些什么來更新程序集以使用更新的版本是創建一個小的XML文件,告訴加載器“你知道我怎么說我想要Foo.DLL v1.4?好吧,實際上如果1.5可用,它可以使用那也是。”

我應該尋找什么? 我看到很多關於C#和.NET的書籍,但沒有關於部署,構建或測試或與語言本身無關的事情。

我同意,書籍中的部署經常被忽略。

如果您對托管Windows應用程序的部署感興趣,我會首先搜索“ClickOnce”。

項目可以引用程序集或項目。

引用另一個程序集/項目時,可以使用引用程序集中的所有公共類/枚舉/結構等。

您不需要在一個解決方案中擁有所有這些。 您可以有三個解決方案,每個流程一個,所有三個解決方案都可以加載Engine和Filter。

此外,您可以讓Process B和Process C引用Engine和Filter的已編譯程序集(.dll)並具有類似的效果。

只要不在程序集的引用中將屬性設置為需要特定版本,就可以自由地更新DLL而不必擔心,只要對DLL進行唯一的代碼更改即可。

此外,我們將過濾器與進程分離的原因(只有一個進程使用它)是因為我們可以獨立於進程部署過濾器,以便不需要更新進程可執行文件。 不管這是不是最好的做法,讓我們來看看吧。 這可能嗎?

我其實更喜歡這種更新方法。 每次更新只更改而不是更改所有內容的文件的開銷更少。

至於使用GAC,我將不會涉及其他復雜程度。

對組件進行防篡改可以通過簽名來完成,這是首先使用GAC所必需的,但只要不需要特定版本,您仍然可以使用。

我的建議是閱讀一本關於.NET框架的書。 這將真正幫助您了解CLR以及您正在做什么。

應用Microsoft .NET Framework編程是一本我非常喜歡閱讀的書。

您提到引擎是共享代碼,這就是您將其放在解決方案下的單獨項目中的原因。 這樣做是沒有錯的,並且沒有必要將此DLL添加到GAC。 在開發階段,您只需添加對引擎項目的引用,您就可以從該程序集中調用代碼。 當您想要部署此應用程序時,您可以使用它部署引擎DLL,或者您可以將引擎DLL添加到GAC(這是另一個蠟球本身)。 除非真的有必要,否則我傾向於依賴GAC部署。 .NET的最佳功能之一是能夠在一個文件夾中部署運行應用程序所需的一切,而無需將內容復制到系統文件夾(即GAC)。

如果你想要從你的處理器動態加載DLL和調用成員方法而不關心特定版本,你可以去幾條路線。 最簡單的方法是在添加引用時將Specific Version屬性設置為False 這將使您可以在以后更改DLL,並且只要您不使用方法簽名,它就不應該成為問題。 第二個選項是MEF (它使用Reflection並將成為.NET 4.0中框架的一部分)。 使用MEF的想法是,您可以掃描實現特定功能的DLL的“插件”樣式文件夾,然后動態調用它們。 這為您提供了一些額外的靈活性,您可以在以后添加新程序集而無需修改引用。

另外需要注意的是,Visual Studio中內置了安裝和部署項目模板,您可以使用這些模板生成用於部署項目的MSI包。 MSDN有很多與此主題相關的文檔,您可以在這里查看:

http://msdn.microsoft.com/en-us/library/ybshs20f%28VS.80%29.aspx

不要使用GAC您的構建機器上,它是一個部署細節。 當您引用DLL時,Visual Studio會自動將DLL復制到應用程序的構建目錄中。 這確保您將使用預期版本的DLL運行和調試。

部署時,您可以選擇。 您可以將DLL與使用它的應用程序一起發送,存儲在EXE安裝文件夾中。 沒有什么特別需要,CLR總能找到DLL,你不必擔心強名稱或版本。 只需將新DLL復制到EXE文件夾即可部署錯誤修復更新。

當您有幾個已安裝的應用程序依賴於DLL時,部署錯誤修復更新可能會開始變得尷尬。 因為您必須重復復制到DLL,每個應用程序一次。 當您更新某些應用程序而不是其他應用程序時,您可能會遇到麻煩。 特別是當DLL接口發生重大變化時,需要重新編譯應用程序。 這是DLL Hell敲門,GAC可以解決這個問題。

我們在MSDN上找到有關此問題的一些指導 我們從兩個單獨的解決方案開始,沒有共享代碼,然后將共性抽象為共享程序集。 我們在分離共享代碼中的更改以僅影響已准備好的項目方面遇到了困難。 我們在開/關時很糟糕。

我們嘗試了

  • 為使用它的每個項目分支共享代碼,並將其包含在解決方案中
  • 在我們進行更改時從共享解決方案復制共享程序集
  • 編碼預構建事件以構建共享代碼解決方案並復制程序集

一切都是真正的痛苦。 我們最終使用了一個包含所有項目的大型解決方案。 我們分支每個項目,因為我們希望將功能更接近生產。 這也分支了共享代碼。 它簡化了很多事情,隨着公共代碼的變化,我們可以更好地了解所有項目中的測試失敗。

就部署而言,我們的構建腳本被設置為構建代碼並僅將已更改的文件(包括程序集)復制到我們的環境中。

默認情況下,項目中有一個硬編碼版本號(1.0.0.0)。 只要不更改它,就可以將所有Filter構建與Process程序集一起使用(它只知道它應該使用1.0.0.0版本)。 然而,這不是最佳解決方案,因為您如何區分各種構建?

另一種選擇是使用相同Process的不同版本的Filter。 您應該將app.config文件添加到Process項目,並包含bindingRedirect元素(請參閱文檔)。 每當運行時查找特定版本的過濾器時,它都會“重定向”到配置中指示的版本。 不幸的是,這意味着雖然您不必更新Process程序集,但您必須使用新版本更新配置文件。

每當遇到版本問題時,您都可以使用Fuslogvw.exe(融合日志查看器)對這些問題進行故障排除。

玩得開心!

烏魯

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM