最近听到很多关于托管扩展框架的描述,虽然很多人明白它的意思,但是却不理解该工具的工作原理。这一工具能帮助客户向WPF程序添加自己的表单吗?我们的菜单中需要这些新表单不过不希望VB源代码被客户重新编译。本文会教大家如何使用托管扩展框架。
听起来这似乎是对MEF的有效应用。你也可以使用相同的方法来应用到WinForms或ASP.NET中,而且c#代码与下文要展示的代码相似。
MEF是一种能够通过简单模型使元件进行互动的扩展模型。MEF会调用部分元件。MEF对于不同模式类型都具有可扩展性,但同时会配备一个属性模型。这样你就可以通过.NET属性定义部件的互动。如果某部件需要什么,它会使用Import属性,如果部件要供给什么,它会使用Export属性。任何部件都可用作主机或客户端,供应商或客户。MEF的这些互动以协议会基础并提供灵活的发掘模型。你的应用程序会向MEF发送请求以提供执行。这样应用程序就可以脱离依赖并让你进行替换执行。
MEF目前还只是在CodePlex上作为一个预览版推出。它位于System.ComponentModel命名空间中,这表明它将会以.NET Framework 4.0中的正式一员出现。某些微软项目都将与之相关,包括VS 2010代码编辑器。在它还未出现在.NET框架中以前,我们都需要下载MEF并将 System.ComponentModel.Composition.dll放到可访问的文章。你还要意识到应用程序接口可能会发生变化。
应用程序将是MEF的主机而客户会写出MEF客户端或扩展。扩展要易于写客户端因为主机必须管理CompositionContainer。我们会按照创建接口,创建扩展,创建WPF主机的步骤来讲解整个过程。WPF主机会向CompositionContainer穿送一个目录,它会指定用于搜索菜单扩展的目录。
扩展支持所订立的协议。最普遍的协议是接口,而这些接口都很简单。
Public Interface IExtension
Sub ShowWindow()
End Interface
客户可以通过执行这一接口来添加扩展并从System.ComponentModel.Composition命名空间中指定Export属性:
Export(GetType(IExtension))> _
_
Partial Public Class First
Implements IExtension
Public Sub ShowWindow() _
Implements Common.IExtension.ShowWindow
End Sub
End Class
你也可以使用任意字符串来确定输出,但是最普遍的扩展是通过一个接口协议来检索。ExportMetadata属性会包含主机能够检索的额外扩展信息,而不需要真正地展示基本对象,这样可以让我们控制示例并保护性能。
设计方案时,将接口设置为由主机和所有扩展组件单独引用。不要在主机和扩展之间建立直接的引用。所有的组件都需要引用 System.ComponentModel.Composition.dll。编译的扩展要放在方便的位置。你可以在属性属性对话框中指定建立的位置。
主机要管理CompositionContainer。CompositionContainer接通幕后的输入与输出,而且它必须了解所能获取的输出。创建一个容器项目级别的变量以清理OnExit。对容器Dispose方法调用会处理所有执行IDisposable的部件:
Protected Overrides Sub OnExit( _
ByVal e As System.Windows.ExitEventArgs)
MyBase.OnExit(e)
If mContainer IsNot Nothing Then
mContainer.Dispose()
End If
End Sub