在MEF中创建一个新实例

时间:2011-08-29 09:21:00

标签: vb.net mef

我正在使用MEF for Plug-in,我创建了一个有{1}的课程

PluginManager

现在想要创建一个新的实例,当我从插件查询时,

我已将PartCreationpolicy设置为Nonshared,但仍无效。

它的解决方案是什么?

1 个答案:

答案 0 :(得分:1)

Lazy<T,TMetadata>类型(与其Lazy<T>对应类型提供延迟实例化(例如延迟加载)。本质上,第一次调用Value属性时,它调用委托函数从容器中获取导出,组合它并返回其值。对Value属性的任何后续调用都将返回相同的值。因此,PartCreationPolicy不太相关,因为尽管这仍然很重要在容器级别,惰性实例只会保持相同的值。

您使用GetExports的解决方案是确保观察到PartCreationPolicy的一种方法,但您必须依赖于必须将正确的CreationPolicy应用于该类型的事实

您可以考虑使用工厂而不是插件类型。有两种方法可以执行此操作,您可以使用ExportFactory<T, TMetadata>允许您每次启动新实例(这包含在MEF的Silverlight变体中,但[Glenn Block也为.NET 4.0发布了它{{} 3}}])。

使用导出工厂,您可以将导入更改为:

<ImportMany()>
Public Property PluginFactories() As ExportFactory(Of IPlugin, IPluginExport)()

并通过ExportLifetimeContext<T>.Value抓取CreateExport()属性返回。

你能做到的另一种方式是,如果你定义另一个合同,我们称之为IPluginFactory,它可能看起来像:

Public Interface IPluginFactory

  Function CreateInstance() As IPlugin

End Interface

<Export(GetType(IPluginFactory))>
Public Class TestPluginFactory Implements IPluginFactory

  Public Function CreateInstance() As IPlugin 
    Implements IPluginFactory.CreateInstance

    Return New TestPlugin()
  End Function

End Class

(对不起,如果语法不太正确,我通常不会做VB)。

现在,您可以将导入更改为:

<ImportMany()>
Pulic Property PluginFactories(Of IPlugin, IPluginExport)()

...并获取您的IPluginFactory实例,然后通过调用工厂的IPlugin方法创建您的CreateInstance实例。您需要考虑的另一件事是,如果您的IPlugin实例需要自己编写(为了满足它自己的部分导入),您需要将其与容器组合。为此,可能更好的是,如果您导出容器实例,那么可以通过工厂构造函数导入它:

Dim container As New CompositionContainer(....)
AttributedModelServices.ComposeExportedValue(container, container)

<Export(GetType(IPluginFactory))>
Public Class TestPluginFactory Implements IPluginFactory

  Private _container As CompositionContainer

  <ImportingConstructor()>
  Public Sub New(container As CompositionContainer)
      _container = container
  End Sub

  Public Function CreateInstance() As IPlugin
    Implements IPluginFactory.CreateInstance

    Dim instance As New TestPlugin()
    AttributedModelServices.ComposeParts(_container, instance)

    Return instance
  End Function

End Class

我的偏好是使用ExportFactory本身,因为您实际上不必传递容器实例,当您从工厂抓取部件时,您可以获得自动实例组合的好处,但是你想要对插件实例的创建方式进行绝对精细的控制,你可以(如上所示)创建一个非常简单的工厂。

传递容器是否正确是你需要提出的另一个问题,因为它确实使你的工厂明确依赖于CompositionContainer,因此可能会使测试变得更复杂一些

我希望您看到的是,MEF有多种方法可以解决同样的问题,您只需要决定什么更适合您的设计。