IAb*_*act 1 c# plugins marshalbyrefobject .net-3.5
抽象类可以用作"主机"和"插件"之间的契约对象吗?这个想法是插件继承了契约(我们称之为适配器).我们也理解框架中的所有参与者都必须继承MarshalByRefObject(MBRO).所以,这就是我们的想法 -
主持人:
class Host : MarshalByRefObject
{
}
Run Code Online (Sandbox Code Playgroud)
合同:
public abstract class PluginAdapter : MarshalByRefObject
{
}
Run Code Online (Sandbox Code Playgroud)
插件:
class myPlugin : PluginAdapter
{
}
Run Code Online (Sandbox Code Playgroud)
这三个都存在于不同的asm中.我们的主机将为每个插件创建一个新的AppDomain,并按如下方式创建PluginAdapter:
{
ObjectHandle instHandle = Activator.CreateInstance(
newDomain, data.Assembly.FullName, data.EntryPoint.FullName);
PluginAdapter adapter = (PluginAdapter)instHandle.Unwrap();
}
Run Code Online (Sandbox Code Playgroud)
编辑:data具体类型在哪里myPlugin.
我们想知道该框架的实施是否有效.我们已经看到使用接口(IPlugin)进行插件派生的文章,以及作为契约的具体类.这些文章还会说可以使用抽象类,但没有给出该实现的示例.是否要求合同是具体的类?
编辑:在Richard Blewett的这个例子中 - C#Reflection - 他使用了一个更简单的实现:
合同:
public interface IPlugIn
{
// do stuff
}
Run Code Online (Sandbox Code Playgroud)
插件:
public class PlugIn : MarshalByRefObject, IPlugIn
{
}
Run Code Online (Sandbox Code Playgroud)
现在,如果使用抽象类作为契约,则插件不能继承合同和MBRO.那么,什么成为可扩展插件框架的最佳实现.我们是否应该继续实施远程操作,尽管最初我们正在开发单机操作?该项目预计将分布在整个网络中,也可能跨越互联网.我们还没有实现Tcp,因为我们正在努力让插件框架的基础知识得到充分理解和操作.
使用环回在单台机器上实现Tcp远程处理是否有意义?
小智 6
imho,抽象类是更好的选择.它主要是因为接口更难以版本化. 此博客文章描述了如果您不使用基类,您可能会遇到的问题.这个规则不仅适用于插件,顺便说一下.
关于你的设计......
插件不应该扩展MBRO.您应该使用您的主机(应该扩展MBRO)来对您的插件进行所有调用,包括处理插件事件.如果您尝试将插件DLL拉到并使用其代理,则很容易无意中将插件DLL加载到您的主应用程序域中.
例如,如果插件为其中一个方法返回IEnumerable,它可能会返回插件程序集中定义的IEnumerable实现.如果这不扩展MBRO,主appdomain将必须加载插件程序集.
我在这里上传了三个处理appdomains的项目:
一个是在appdomains中使用回调,第二个是跨appdomain事件处理,第三个是插件示例.
在插件示例中,应用程序定义了一个插件接口(它是一个演示,而不是最佳实践!)和一个插件主机.该应用程序从磁盘加载一个插件程序集raw,并通过插件主机代理将其传递到插件appdomain,然后加载它.插件主机然后实例化插件并使用它.但是当主机将插件程序集中定义的类型返回到应用程序appdomain时,插件程序集将加载到主应用程序域中,从而使整个插件变得毫无意义.
最好避免这种情况是为插件提供一个抽象基类,它没有标记为可序列化并且不扩展MBRO,并且只返回您从插件域跨越边界定义的基元或密封类型.
注意:项目都是4.0 RC.你需要这个或更多才能运行它们.否则,您必须手动编辑项目文件或重建它们以使它们在b2或2008中运行.
| 归档时间: |
|
| 查看次数: |
1840 次 |
| 最近记录: |