插件体系结构 - 让MDI父表单意识到DLL中的子项

时间:2010-01-25 21:54:14

标签: .net vb.net plugins architecture

我正在为我公司的内部业务系统试验插件架构。我已经设法读取插件文件夹中的所有.DLL,它实现了一个特定的接口。我想弄清楚的是“主机”MDI父应用程序和将在.DLL中形成的表单之间的最佳通信方法,我打算将其作为MDI子项。

目前,我只返回.DLL中的ToolStripMenuItem对象以添加到MDI Parent。我还测试了.DLL中连接到ToolStripMenuItems的事件是否传播到.DLL中的代码。我还设法通过界面返回一个Form对象并打开该表单,因为正在“扫描”插件文件夹。

但是,我不清楚如何制作这些形式的MDI儿童。此外,生活在.DLL中的任何其他形式也必须是MDI儿童。我创建了一个VS 2008 Addin项目,只是为了看看发生了什么,似乎Addin接受了一个Application对象,它将它添加到ToolStripMenuItems并执行其他操作。在.DLL中构建菜单的代码。这与我到目前为止所做的相反,MDI从每个.DLL请求ToolStripMenuItem并将返回的对象添加到它自己的菜单中。

设计我的插件架构是否能以同样的方式接受应用程序对象,这是我可以将表单作为MDI子项打开的唯一方法?我是否要求其他人,目前我不知道,因为不将应用程序对象传递给.DLL而头疼?

1 个答案:

答案 0 :(得分:4)

多年前我们做过类似的事情。我们如何处理它是通过创建一个由PluginManager和插件实现的接口。

插件管理器实现了类似于此的界面:

    ''' <summary>
'''The IPluginManager interface is implemented by whatever component manages your gui
'''It provides a means for plugins to access GUI elements of the application
''' </summary>
Public Interface IPluginManager

    ''' <summary>
    '''The MDIForm property allows the plugin to display itself
    '''inside of the application's main MDI form (ie.  plugin.form.mdiparent=mdiform)
    ''' </summary>
    ReadOnly Property MDIForm() As Form
    ReadOnly Property Toolbar() As ToolBar

    ''' <summary>
    '''Allows the plugin to request that the application's main menu be updated
    ''' </summary>
    ''' <param name="Menu">The menu to add to the main menu</param>
    Sub UpdateMainMenu(ByVal Menu As Menu)

    ''' <summary>
    '''Allows the plugin to request that the application's workspace toolbar be updated
    ''' </summary>
    ''' <param name="Buttons">the collection of toolbar buttons to add to the toolbar</param>
    Sub UpdateToolbarButtons(ByVal Buttons As ToolBar.ToolBarButtonCollection)

End Interface

插件实现了这个界面:

    ''' <summary>
'''The IPlugin interface is implemented by all plugins
'''It provides a standardized means for the pluginmanager
'''to communicate with a plugin, without knowing the plugin explicitly
''' </summary>
Public Interface IPlugin

    ''' <summary>
    '''Allows the plugin to be intialized first before it asked to run
    ''' </summary>
    Sub Initialize()

    ''' <summary>
    '''Allows the pluginmanager to register itself with the plugin
    '''so the plugin can listen to events from the pluginmanager
    ''' </summary>
    ''' <param name="PluginManager">A plugin manager that implements the IPluginManager interface</param>
    Sub RegisterPluginManager(ByVal PluginManager As IPluginManager)

    ''' <summary>
    '''Requests the plugin to run its functionality
    ''' </summary>
    Sub Run()

End Interface

一旦应用程序启动,PluginManager会找到所有可用的插件(听起来你已经有了这个工作),然后实例化每个插件,为每个插件注册自己。然后PluginManager初始化然后运行插件。

在插件方面,当插件初始化或运行时(根据您的需要),您只需将插件表单的MDIParent属性设置为IPluginManager界面中提供的MDIForm。而且中提琴!

两者之间的合约非常简单,您可以轻松更改或扩展。