2017-08-29 67 views
0

我一直在觀察ReSharper創建的解決方案的體系結構視圖,當我注意到一些項目引用沒有編譯時間用法,這是否意味着我可以更改程序集在運行時?引用沒有編譯時使用

回答

1

簡而言之,編譯時使用意味着即使刪除引用,代碼也會編譯。您無法直接從此聲明中獲取有關運行時的任何信息。如果你只是刪除這個引用,它甚至可能是你的應用程序運行得很好。也可能是你的引用有些混亂,編譯器不知道它。這可能是因爲引用是實現您編譯的接口,或者您正在運行時手動查找它(請參閱Florians答案)。如果你真的想,你也可以用反射來隱藏它。但是這也需要在運行時手動加載程序集。

在編譯時,編譯器會將新的二進制文件鏈接到引用程序集中的相應代碼。這將允許在運行時自動加載程序集。它也會將常量值複製到你的程序集中。

雖然你應該非常小心,但你可以在編譯和運行之間更改引用的程序集。如果方法簽名更改,則編譯時引用將中斷。

在運行時,引用程序集將在您嘗試與它們交互時加載。裝配完成後,它不能直接卸載。您只能卸載AppDomains。因此,如果您想在運行時更改程序集,請查看AppDomains。

那麼,那些非編譯時引用的用意是什麼呢? Florian在其他答案中提到了使用這種最常見的體系結構:插件。還有其他依賴關係,您希望通過接口將代碼與實際實現分開。然後,您的項目引用無編譯時依賴關係,僅用於將實現交付給實際應用程序。否則,您需要將其添加到您的交付和調試過程中,這可能會很痛苦,具體取決於您的項目。

+0

因此,我編譯我的解決方案中的項目。他們現在在我的工作目錄中。所以在我的解決方案中,我有兩個項目沒有編譯時間的用法,這是否意味着我可以單獨編譯其中一個項目(而不是整個解決方案),現在我有工作目錄(使用舊版本的項目1程序集)並新創建項目1的組裝。所以你說我可以用工作目錄中的舊工具更改新創建的程序集,通過與AppDomain一起玩,進程仍在運行(也許有些時間停工)? – kuskmen

+0

這樣做的關鍵是儘可能減少停機時間,而無需啓動此過程的新實例,因爲例如我的解決方案可能需要大量時間來編譯/優化等。我不想通過該過程每次我對沒有編譯時間的項目進行更改時使用 – kuskmen

+0

是的,如果您使用AppDomains,則應該能夠設置一些邏輯來實現此目的。看看例如https://www.brad-smith.info/blog/archives/500的一些想法 –