Vb.net 铸造界面与MEF

Vb.net 铸造界面与MEF,vb.net,interface,mef,Vb.net,Interface,Mef,我对MEF有以下问题: 主机要使用的接口定义: Public Interface IExecuteDoSomething Inherits IAddinSettings Event DataReceived As EventHandler(Of DataReceivedEventArgs) Function DoSomething() As Boolean End Interface Public Class DataReceivedEventArgs Inheri

我对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
公共类1
实现SharedLibrary.IExecuteDoSomething
实现SharedLibrary.IAddinSettings
私有附加设置作为新的共享库。附加设置(“测试”)
作为布尔值的公共函数DoSomething()实现SharedLibrary.IExecuteDoSomething.DoSomething
MsgBox(“我做了些什么”)
返回真值
端函数
公共事件DataReceived(ByVal sender作为对象,ByVal e作为SharedLibrary.DataReceivedEventArgs)实现SharedLibrary.IExecuteDoSomething.DataReceived
公共只读属性设置()作为SharedLibrary.AddinSettings实现SharedLibrary.IadInSettings.Setting
得到
返回\u附加设置
结束
端属性
末级
主持人:

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
公共类表单1
私有子表单1_Load(ByVal发送方作为System.Object,ByVal e作为System.EventArgs)处理MyBase.Load
Dim目录作为新的Hosting.AggregateCatalog
Dim d作为新的Hosting.DirectoryCatalog(“…指向dlll的路径”)
catalog.Catalogs.Add(d)
Dim container=新的Hosting.CompositionContainer(目录)
将批处理设置为新的Hosting.CompositionBatch
batch.AddPart(Me)
container.Compose(批处理)
对于dos中的每个dd
AddHandler dd.DataReceived,testevent的地址
下一个
端接头
公共dos作为IEnumerable(属于SharedLibrary.IExecuteDoSomething)
私有子按钮1\u单击(ByVal sender作为System.Object,ByVal e作为System.EventArgs)处理按钮1。单击
对于dos中的每个d
d、 DoSomething()
下一个
端接头
私有子testevent(ByVal发送方作为对象,ByVal e作为SharedLibrary.DataReceivedEventArgs)
MsgBox(“收到的事件:&e.Message”)
端接头
私有子按钮2\u单击(ByVal sender作为System.Object,ByVal e作为System.EventArgs)处理按钮2。单击
Dosomethingelse(DirectCast(dos、System.Collections.Generic.List(SharedLibrary.iaddings)))
端接头
私有子Dosomethingelse(byval设置为IEnumerable(属于SharedLibrary.iaddings))
端接头
末级
在执行Button2_Click例程之前,一切似乎都正常工作,然后抛出一个InvalidCastException,其中包含以下信息:
无法将类型为“System.Collections.Generic.List
1[SharedLibrary.IExecuteDoSomething]”的对象强制转换为类型为“System.Collections.Generic.List
1[SharedLibrary.iaddings]”


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

我怀疑您实际上遇到了协方差问题-这是此类问题的典型原因。
列表
不是
列表
,即使
IBar
扩展了
IFoo

如果您使用的是.NET 3.5,解决此问题的最简单方法是删除
DirectCast
,改为使用:


谢谢,如果你提到最简单的方法,还有别的吗?我已经读过一些关于enumerable.cast的内容,建议避免这种情况(运行时转换?)转换必须是运行时转换,因为这两种列表类型不兼容。有人可能添加了一个IExecutedo的实现,但它没有实现IAddinSettings。
Dosomethingelse(dos.Cast(Of SharedLibrary.IAddinSettings))