1

如果我接下来的解释不够合理,我现在道歉;我以它而闻名,尽管我尝试不这样做。

我正在编写一个使用用户定义插件的服务。我试图通过使用共享程序集中定义的接口来隔离它们——将它们的程序集排除在服务的 appdomain 之外。

让我感到沮丧的是抽象基类的使用。某些接口的所有实现都具有共同的功能,因此抽象基类是有意义的。如果一个抽象基础在服务程序集中,那么任何子类化它的插件都会将它们的程序集拖到服务的应用程序域中。但是,服务使用的抽象基础(具有内部设置器和公共获取器的属性)中有内部成员,因此它需要与服务位于同一程序集中才能实现。

看起来我想要的似乎是不可能的,但我也相信这是因为我采取了错误的方法。我正在拼命地尝试在这个练习中更好地利用好的模式和实践,并在此过程中不断学习。

4

3 回答 3

0

您可能想要的是一个具有抽象基类的接口,该基类实现了接口和派生类可以继承。在这种情况下,您可以保持与接口的分离,但仍为实现提供抽象基类。这还具有抽象基类是可选的优点。

于 2009-12-06T19:21:18.993 回答
0

如果您要避免的问题是将插件程序集泄漏到您的服务 AppDomain 中,那么无论您是否有内部成员,都不会遇到该问题。您只需要服务程序集在插件域中可用(而不是相反),并且您可能必须在服务程序集中定义共享类型而不是单独的程序集(如果您确实需要“内部”另一个组件)。

假设您PluginBase在 ServiceLib.dll 中定义了抽象基类。然后,您可以在主服务 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 = "...";
于 2009-12-06T19:34:53.463 回答
0

(供我和可能其他人将来参考)

事实证明,这是一个毫无意义的练习。

一旦插件创建的对象的代理在其他应用程序域中可用,该服务定义的基类中以内部方式使用服务的任何内容(如针对集合的查找),它都会针对服务对象的副本进行操作插件的 appdomain,而不是我试图提供的单例。

我想我要么放弃我的多应用程序域任务,要么放弃内部做任何事情。如果没有内部操作,则基类可以从服务中分离出来,但它必须像其他一切一样与服务交互。

我确实喜欢学习,但我不欣赏一路上头上的颠簸。

于 2009-12-13T17:27:56.317 回答