C# 抽象基类和应用域

C# 抽象基类和应用域,c#,.net,appdomain,abstract,isolation,C#,.net,Appdomain,Abstract,Isolation,如果我接下来的解释没有足够的意义,我现在道歉;我以它而闻名,尽管我试图做其他事情 我正在编写一个使用用户定义插件的服务。我正试图通过使用共享程序集中定义的接口来隔离它们——将它们的程序集排除在服务的appdomain之外 让我头疼的是抽象基类的使用。有些接口的所有实现都有共同的功能,因此抽象基类是有意义的。如果抽象基在服务程序集中,那么将其子类化的任何插件都会将其程序集拖到服务的appdomain中。但是,服务使用的抽象基中有内部成员(具有内部setter和公共getter的属性),因此它需要与

如果我接下来的解释没有足够的意义,我现在道歉;我以它而闻名,尽管我试图做其他事情

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

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


似乎我想要的是不可能的,但我也相信这是因为我采取了错误的方法。在本练习和学习过程中,我一直在努力更好地利用好的模式和实践。

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

如果您试图避免的问题是插件程序集泄漏到您的服务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中可用,该服务定义的基类中任何以内部方式使用该服务(如对集合进行查找)的内容都将针对插件appdomain中服务对象的副本而不是我试图提供的单例进行操作

我想我要么放弃我的多appdomain任务,要么放弃在内部做任何事情。如果没有内部操作,基类可以从服务中分离,但是它必须像其他操作一样与服务交互


我确实喜欢学习,但我不喜欢一路上头上的磕磕绊绊。

这就是我目前正在做的事情。但是,当我设置基类中定义的内部属性时,它会将插件的程序集带入服务的appdomain。我猜这是因为它是一个抽象的基,需要从插件程序集中获取类型信息(这确实是一个猜测)。嗯,我刚刚尝试了这个,看起来我看到了与您相同的行为。。。一旦将类加载到另一个AppDomain中,它就会将插件程序集加载到主AppDomain中。当您使用接口时,不会发生这种情况,但这当然无助于您定义通用实现。似乎有效的方法是定义一个接口和一个实现该接口的基类;然后,当您加载类型时,您只对接口进行强制转换,而它不会加载其他程序集。由于接口不允许混合可见性,所以这可能还不能完全满足您的需要。由于接口是关键的,所以我最终要做的是让抽象基类实现一个内部接口。该内部接口实现公共接口,因此基类同时实现公共成员和内部成员。如果一个对象是基类的子类,那么我知道我可以访问一个可以设置的内部接口属性。这似乎将插件程序集排除在主appdomain之外!