0

我对 MEF 有以下问题:

主机使用的接口定义:

Public Interface IExecuteDoSomething
   Inherits IAddinSettings

   Event DataReceived As EventHandler(Of DataReceivedEventArgs)
   Function DoSomething() As Boolean

End Interface

Public Class DataReceivedEventArgs
   Inherits EventArgs

   Public Sub New(ByVal message As String)
      Me.Message = message
   End Sub

   Public Message As String
End Class

主机内的一些其他代码所需的额外接口:

    Public Interface IAddinSettings
        ReadOnly Property Setting() As AddinSettings
    End Interface

    Public Class AddinSettings
        Private _Name As String
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property

        Public Sub New(ByVal name As String)
            Me.Name = name
        End Sub
    End Class

提供导出的类:

    <Export(GetType(SharedLibrary.IExecuteDoSomething))> Public Class Class1
        Implements SharedLibrary.IExecuteDoSomething
        Implements SharedLibrary.IAddinSettings

        Private _Addinsettings As New SharedLibrary.Addinsettings("Test")

        Public Function DoSomething() As Boolean Implements SharedLibrary.IExecuteDoSomething.DoSomething
            MsgBox("i did something")
            Return True
        End Function


        Public Event DataReceived(ByVal sender As Object, ByVal e As SharedLibrary.DataReceivedEventArgs) Implements SharedLibrary.IExecuteDoSomething.DataReceived

        Public ReadOnly Property Setting() As SharedLibrary.AddinSettings Implements SharedLibrary.IAddinSettings.Setting
            Get
                Return  _Addinsettings
            End Get
        End Property
    End Class

主人:

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim catalog As New Hosting.AggregateCatalog
        Dim d As New Hosting.DirectoryCatalog("..path to dlll..")
        catalog.Catalogs.Add(d)
        Dim container = New Hosting.CompositionContainer(catalog)
        Dim batch As New Hosting.CompositionBatch
        batch.AddPart(Me)
        container.Compose(batch)
        For Each dd In dos
            AddHandler dd.DataReceived, AddressOf testevent
        Next
    End Sub

    <Import()> Public dos As IEnumerable(Of SharedLibrary.IExecuteDoSomething)

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For Each d In dos
            d.DoSomething()
        Next
    End Sub

    Private Sub testevent(ByVal sender As Object, ByVal e As SharedLibrary.DataReceivedEventArgs)
        MsgBox("Event received: " & e.Message)
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dosomethingelse(DirectCast(dos, System.Collections.Generic.List(Of SharedLibrary.IAddinSettings))) 
    End Sub
    Private Sub Dosomethingelse(byval settings as IEnumerable(Of SharedLibrary.IAddinSettings))
    End Sub 

End Class

在执行 Button2_Click 例程之前,一切似乎都运行良好,然后抛出 InvalidCastException 并显示以下信息:
无法转换类型为“System.Collections.Generic.List 1[SharedLibrary.IExecuteDoSomething]' to type 'System.Collections.Generic.List1[SharedLibrary.IAddinSettings]”的对象。

我该如何解决这个问题,因为导入的对象实现了这两个接口?

4

1 回答 1

1

我怀疑您实际上遇到了协方差问题 - 这是此类问题的典型原因。AList<IFoo>不是a即使extends 。_List<IBar>IBarIFoo

如果您使用的是 .NET 3.5,在您的情况下解决此问题的最简单方法是删除DirectCast并改为使用Enumerable.Cast

Dosomethingelse(dos.Cast(Of SharedLibrary.IAddinSettings))
于 2009-03-13T10:38:12.160 回答