2009-12-06 74 views
1

我現在很抱歉,如果我即將解釋沒有足夠的意義;我爲它而聞名,儘管我試圖做其他事情。抽象基類和應用程序域

我正在寫一個服務,使用用戶定義的插件。我是嘗試使用來隔離它們 - 通過使用共享程序集中定義的接口,將它們的組件保留在服務的appdomain之外。

什麼讓我害怕抽象基類的使用。對於某些接口的所有實現來說,這些功能是通用的,所以抽象基類是有意義的。如果一個抽象基礎在服務組合中,那麼無論它的子類是什麼插件都會將它們的組件拖入服務的appdomain中。但是,服務使用的抽象基礎中有內部成員(具有內部設置者和公共獲取者的屬性),因此它需要與服務在同一個程序集中才能實現。

看來我想要的是不可能的,但我也相信這是因爲我採取了錯誤的做法。我正拼命地嘗試在此練習中更好地使用良好的模式和實踐,並一路學習。

+0

由於接口是關鍵,我最終做的是讓抽象基類實現一個內部接口。該內部接口實現了一個公共接口,所以基類實現了公共成員和內部成員。如果一個對象是基類的子類,那麼我知道我可以訪問我可以設置的內部接口屬性。這似乎確保插件組件不在主應用程序域中! – redman 2009-12-07 16:28:19

回答

0

你可能想要的是一個接口,它帶有一個抽象基類,它實現了接口,派生類可以繼承它。在這種情況下,您可以保持與界面的分離,但仍然提供實現的抽象基類。這也具有抽象基類是可選的優點。

0

如果您試圖避免的問題是將插件程序集泄漏到您的服務AppDomain中,那麼無論您是否擁有內部成員,都不會出現該問題。您只需要服務程序集在插件域中可用(而不是其他方式),您可能必須在服務程序集中定義共享類型而不是單獨的程序集(如果您確實需要「內部」另一個組件)。

想象一下,您在ServiceLib.dll中定義了抽象基類PluginBase。然後,您可以有這樣的代碼在你的主要服務的AppDomain:

// Create a new AppDomain for the plugin 
AppDomain pluginDomain = AppDomain.CreateDomain("PluginDomain", null, new AppDomainSetup()); 

// Instantiate the plugin type (in the new AppDomain) 
// Note: assumes that PluginBase is MarshalByRefObject 
PluginBase plugin = (PluginBase)domain.CreateInstanceAndUnwrap("PluginLib", "PluginLib.PluginImp"); 

// Set any internal stuff now 
plugin.InternalDetails = "..."; 
+0

這實際上是我目前正在做的。但是,當我設置基類中定義的內部屬性時,就是將插件的程序集帶入服務的appdomain。我猜測這是因爲它是一個抽象基礎,並且需要來自插件程序集的類型信息(它確實是一個GUESS)。 – redman 2009-12-06 19:50:18

+0

嗯,我剛剛嘗試過這一點,它看起來像我看到了與你一樣的行爲......只要你加載類到另一個AppDomain中,它就會將插件程序集加載到主AppDomain中。當你使用一個接口時,這不會發生,但這當然不會幫助你定義通用實現。看來工作的是定義一個接口和一個實現接口的基類;那麼當你加載這個類型時,你只能轉換到這個接口,並且它不會加載其他程序集。由於界面不允許混合的可視性,這仍然可能不完全符合你的要求。 – bobbymcr 2009-12-06 20:21:38

0

(對於我和其他可能的備查)

事實證明,這是一個有些無意義的鍛鍊。

一旦插件創建的對象的代理在其他應用程序域中可用,則該服務定義的基類中的任何內容(如針對集合的查找)都會使用該服務,它會針對插件的appdomain中的服務對象,而不是我試圖提供的單例。

我想我要放棄我的多appdomain任務或放棄在內部做任何事情。如果沒有內部操作,基類可以從服務中分離出來,但是它必須與其他服務一樣與服務交互。

我很喜歡學習,但我不欣賞沿途的顛簸。