在MEF中创建一个新实例
我正在使用 MEF 作为插件,我创建了一个具有属性的类 PluginManager
<ImportMany()>
Public Property Plugins() As Lazy(Of IPlugin, IPluginExport)()
现在想要创建一个新实例,当我从插件查询时,
我已经将 PartCreationpolicy 设置为 Nonshared,但仍然不是在职的。
有什么解决办法吗?
I am using MEF for Plug-in, I made one class PluginManager
which has propety
<ImportMany()>
Public Property Plugins() As Lazy(Of IPlugin, IPluginExport)()
Now want to create a new instance of when i query from plugins,
I have already set PartCreationpolicy as Nonshared, but still its not working.
What is solution for it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Lazy
类型(与其Lazy
对应项一样,提供延迟实例化(例如延迟加载)。本质上,第一次Value
属性被调用时,它会调用一个委托函数,该函数从容器中获取导出,组合它并返回其值,因此对Value
属性的任何后续调用都将返回相同的值。对此,PartCreationPolicy
不太相关,因为尽管这在容器级别仍然很重要,但惰性实例只会保留相同的值,您使用
GetExports
的解决方案是。确保遵守PartCreationPolicy
的一种方法,但您必须依赖于必须将正确的CreationPolicy
应用于该类型的事实,您可以考虑使用工厂 。你的有两种方法可以做到这一点,您可以使用
ExportFactory
它允许您每次启动新实例(这包含在 MEF 的 Silverlight 变体中,但是 [ Glenn Block 还针对 .NET 4.0 发布了它@他的 SkyDrive - Composition.Initialization.Desktop])。使用导出工厂,您可以将导入更改为:
并通过
CreateExport()
获取ExportLifetimeContext.Value
属性返回。另一种方法是,如果您定义另一个合约,我们将其称为
IPluginFactory
,它可能看起来像:(抱歉,如果语法不太正确,我通常不做 VB )。
现在,您可以将导入更改为:
...并获取 IPluginFactory 实例,然后通过调用工厂的
CreateInstance
方法创建您的IPlugin
实例。您需要考虑的另一件事是,如果您的IPlugin
实例需要自行组合(以满足其自己的部分导入),则需要将其与容器组合。为此,如果您导出容器实例,那么您可以通过工厂构造函数导入它:我的偏好是使用
ExportFactory
本身,因为您实际上并不这样做必须传递容器实例,并且当您从工厂获取部件时,您可以获得自动实例组合的好处,但是如果您想要对插件实例的创建方式进行绝对细粒度的控制,您可以(如上所示)创建相当简单的工厂。传递容器是否正确是您需要问的另一个问题,因为它确实使您的工厂明确依赖于
CompositionContainer
,因此可能会使测试变得更加复杂。我希望您看到的是,使用 MEF,您可以通过多种方法解决同一问题,您只需决定哪种方法更适合您的设计。
The
Lazy<T,TMetadata>
type (like itsLazy<T>
counterpart provides of deferred instantiation (e.g. lazy loading). Essentially, the first time theValue
property is called, it calls a delegated function which grabs the export from the container, composes it and returns its value. Any subsequent call to theValue
property will return the same value. Because of this,PartCreationPolicy
is less relevant, because although that still matters at the container level, the lazy instance will only hold onto the same value.You're solution to use
GetExports
is one method of ensuring thePartCreationPolicy
is observed, but you have to rely on the fact that the correctCreationPolicy
must be applied to the type.What you could consider is using factories instead of your plugin types. There are two ways of doing this, you could use
ExportFactory<T, TMetadata>
which allows you to spin up new instances each time (this is included in the Silverlight variant of MEF, but [Glenn Block also released it for .NET 4.0 @ his SkyDrive - Composition.Initialization.Desktop]).With export factory, you could change your imports to:
And grab the
ExportLifetimeContext<T>.Value
property return throughCreateExport()
.The other way you could do it, is if you define another contract, let's call it
IPluginFactory
, which could look like:(Sorry if the syntax isn't quite right, I don't usually do VB).
Now, you could change your import to be:
...and grab your IPluginFactory instance, then create your
IPlugin
instance by calling the factory'sCreateInstance
method. The other thing you need to consider, is that if yourIPlugin
instance requires composing itself (to satisfy it's own part imports), you need to compose this with your container. To that end, what might be nice, is if your export your container instance, that way you could import it via your factory constructor:My preference would be to use
ExportFactory
itself, as you don't really have to pass around a container instance, and you get the benefits of automatic instance composition when you grab the part from the factory, but if you want absolute fine grained control over how the plugin instance is created, you can (as shown above) create quite a simple factory.Whether or not it is right to be passing the container around is another question you'd need to ask, as it does make your factories explicitly dependent on
CompositionContainer
, and thus might make testing it a little more complicated.What I hope you see, is that with MEF there are a myriad of ways you could solve the same problem, you just have to decide what fits better into your design.