2012-05-21 47 views
3

我已經構建了一個後端,以便業務邏輯放置在運行時加載的dll中。使用ShadowCopyFiles = true和文件系統監視,我可以在不重新啓動主機進程的情況下修改業務邏輯。AppDomain隔離問題

到目前爲止好...

我們稱之爲主機應用程序域A,和孩子們的一個B.

不幸的是,如果我做這被B引用在裝配C,變化,但不是A,當B重新加載時,這些更改不會反映出來。我認爲這是因爲A加載C本身。我必須採取哪些措施來防止A加載C?

這是使用A到負載B代碼:

 AppDomainSetup appDomainSetup = new AppDomainSetup(); 
     appDomainSetup.CachePath = ServiceDLLPath + @"\Shadow"; 
     appDomainSetup.ShadowCopyFiles = "true"; 

     ad = AppDomain.CreateDomain(assemblyName, null, appDomainSetup); 
     ad.InitializeLifetimeService(); 
     try 
     { 
      service = (IService)ad.CreateInstanceFromAndUnwrap(assemblyName, 
            "AppName.Services." + typeName); 
      service.Start(); 
     } 
     catch (Exception e) 
     { 
      LogManager.Log("AppDomain load failed: " + e.Message); 
      return false; 
     } 

回答

0

如果A引用CA是「主」,你不能重裝C沒有停止和重新啓動的過程。

一種可能性是製作一個非常薄的墊片AppDomain,引導A AppDomain(並且可以重新啓動它),但重新設置過程可能與性能配置文件大致相同。

另一種(看似更加明智的)方法是使A和它的依賴關係獨立於C所使用的依賴關係,並且對於重疊的程序集只是使它們足夠穩定以至於不需要經常更改它們。

+0

感謝您的迴應Chris。 A沒有明確提到C.但是引用B,引用了C,那應該是好的,不是? –

+0

當我構建A時,我可以看到它創建了C的本地副本,儘管它並沒有直接引用,所以我猜想存在某種程序集的遞歸搜索。 –

+0

引用是隱式遞歸的,是的。如果'A'引用'B','B'引用'C',則加載'A'將加載'C'。 –

0

好吧我通過創建'接口'組件來解決它。

因此,如果這組件被稱爲X,鏈條現在是:

A - > X < - B - 「ç

(原:A - >乙 - > C)

我現在可以對B或C進行更改,這會在appDomain B被銷燬並由A重新啓動時得到反映。

編輯,按照Tim的要求,提供更多詳細信息。

appdomain A中的代碼沒有改變,你可以看到我的問題。一個需要注意的唯一的事情是IService類型定義的位置:

service = (IService)ad.CreateInstanceFromAndUnwrap(assemblyName, 
           "AppName.Services." + typeName); 

一旦IService被轉移到一個特定目的建造組裝,我能夠刪除以某種方式結束了連接在B和A引用A到C.基本上Chris所說的一切都是正確的,只是它並不總是清楚路徑是什麼。

+0

小心向我們展示你如何做的一個片段?至少您的文章將是一個有價值的答案,可能也會收到它的學分。 :-) –

+0

沒有太多的代碼顯示有關更改,請參閱我更新的答案。如果您有興趣,我可以共享監控/重新啓動代碼。很可能會接受克里斯的答案。 –

0

閱讀答案和評論,這聽起來像你最好將業務邏輯包裝到WCF服務中。您可以使用網管來最小化在同一臺PC上運行的開銷。您還應該看看MEF構建應用程序的可擴展性。不幸的是,MEF的設計目的並不在於讓您在不重新啓動主機應用程序的情況下卸載並替換插件

+0

如果我再次這樣做,我會沿着這條路線走下去。似乎像加載邏輯動態使用AppDomains是不值得的麻煩。我甚至不確定這種appdomain方法在什麼情況下勝過「每個服務一個進程+ WCF」。 –