【问题标题】:MEF import is creating two instances of every partMEF 导入为每个部分创建两个实例
【发布时间】:2011-11-25 10:29:11
【问题描述】:

我在运行时使用 MEF 组合多个组件,但是当我使用元数据属性时,它会使集合中的部件数量增加一倍。

在检查 container.ComposeParts 时,我可以看到包含 11 个 IStages 实现的 dll 被加载一次,并且只出现了所需的 11 个部分,但是当它将私有属性阶段解析为 IEnumerable(Of Lazy(Of IStages, IStagesMetadata) ) 实例的数量翻了一番,达到 22。循环遍历集合我可以看到它们与元数据中的 ID 重复。

如果我不在导出或导入上使用元数据属性,那么我会得到预期的 11 个部分。

导出属性

Imports System.ComponentModel.Composition

<MetadataAttribute(), AttributeUsage(AttributeTargets.Class, AllowMultiple:=False)>
Public Class StagesMetadataAttribute
    Inherits ExportAttribute

    Public Property StageID As Byte
    Public Property Version As String

    Public Sub New()
        MyBase.New(GetType(IStages))
    End Sub

End Class

零件示例

Imports System.ComponentModel.Composition
Imports VFRAME.QUALITY.GOODSIN.ESCALATE.INTERFACES

<Export(GetType(IStages))>
<StagesMetadata(StageID:=1, Version:="v1.0.0.0")>
Public Class Stage1
    Implements IStages

    Public Function ProcessEscalation(failure As InspectionFaultsModel) As InspectionFaultsModel Implements IStages.ProcessEscalation
        Return Nothing
    End Function

End Class

导入端构造函数

Using catelog As New DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory)
    Using container As New CompositionContainer(catelog)
        Try
            container.ComposeParts(Me)
        Catch ex As CompositionException
            _compositionComplete = False
        End Try
    End Using
End Using

大量进口

<ImportMany()>
Private Property Stages As IEnumerable(Of Lazy(Of IStages, IStagesMetadata))

导入元数据接口

Public Interface IStagesMetadata
    ReadOnly Property StageID As Byte
    ReadOnly Property Version As String
End Interface

知道问题出在哪里吗?

【问题讨论】:

    标签: .net vb.net mef


    【解决方案1】:

    想通了

    如果您使用 Export 和 StagesMetadata 装饰部件,它会为部件创建 2 个导出定义,因为 StagesMetadataAttribute 继承自 ExportAttribute

    <Export(GetType(IStages))>
    <StagesMetadata(StageID:=1, Version:="v1.0.0.0")>
    Public Class Stage1
        Implements IStages
    
        Public Function ProcessEscalation(failure As InspectionFaultsModel) As InspectionFaultsModel Implements IStages.ProcessEscalation
            Return Nothing
        End Function
    
    End Class
    

    没有考虑到愚蠢。

    【讨论】:

    • 这是正确的,您提供了两个出口,同一合同的同一类型。您已经创建了一个自定义导出属性 (StagesMetadataAttribute),因此只需删除额外的 [Export(typeof(IStages))] 导出,您就可以开始使用了。此外,如果您这样做,您可能需要重命名自定义导出属性以更好地表示其功能,例如StagesMetadataAttribute -> ExportStagesAttribute.
    • 另外,出于个人喜好,我通常使用元数据合约来装饰我的导出属性。您不需要这样做,但它可以很好地提醒您,如果您更改元数据协定,导出属性也应该更新以反映它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多