我正在使用MEF for Plug-in,我创建了一个有{1}的课程
PluginManager
现在想要创建一个新的实例,当我从插件查询时,
我已将PartCreationpolicy设置为Nonshared,但仍无效。
它的解决方案是什么?
答案 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有多种方法可以解决同样的问题,您只需要决定什么更适合您的设计。