【问题标题】:Abstract base classes and appdomains抽象基类和应用程序域
【发布时间】:2009-12-06 19:13:51
【问题描述】:

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

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

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

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

【问题讨论】:

  • 由于接口是关键,我最终做的是让抽象基类实现一个内部接口。该内部接口实现了一个公共接口,因此基类同时实现了公共和内部成员。如果一个对象是基类的子类,那么我知道我可以访问我可以设置的内部接口属性。这似乎确实将插件程序集排除在主应用程序域之外!

标签: c# .net appdomain abstract isolation


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    如果您试图避免的问题是将插件程序集泄漏到您的服务 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 = "...";
    

    【讨论】:

    • 这实际上是我目前正在做的事情。但是,当我设置基类中定义的内部属性时,它会将插件的程序集带入服务的 appdomain。我猜这是因为它是一个抽象基础,并且需要插件程序集中的类型信息(它确实是一个 GUESS)。
    • 嗯,我刚试过这个,看起来我看到的行为和你一样……只要你将类加载到另一个 AppDomain 中,它就会将插件程序集加载到主应用程序域。当您使用接口时,这不会发生,但这当然无助于您定义通用实现。似乎可行的是定义一个接口和一个实现该接口的基类;然后当你加载类型时,你只转换到接口,它不会加载其他程序集。由于界面不允许混合可见性,这可能仍然不能完全满足您的要求。
    【解决方案3】:

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2017-07-09
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 2015-03-28
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多