2009-03-13 12 views
0

IはMEFと、次のような問題た:鋳造インターフェース及びMEF

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 
:ホスト内のいくつかの他のコードが必要とする

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 

余分なインターフェース:

インタフェース定義は、ホストによって使用されます

エクスポートを提供するクラス:

<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 

ホスト:
型のオブジェクトをキャストすることができません「System.Collections.Generic.List 1[SharedLibrary.IExecuteDoSomething]' to type 'System.Collections.Generic.List

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がが情報でスローされ、実行されるまで正常に動作するようです1 [共有ライブラリ.IAddinSettings] '。

インポートしたオブジェクトが両方のインターフェイスを実装しているため、この問題をどのように解決できますか?

答えて

1

私はあなたが実際に共分散問題に遭遇していると思われます。これが、このような問題の典型的な原因です。 List<IFoo>は、IBarIFooであっても、でなく、aList<IBar>である。

は、.NET 3.5を使用している場合は、あなたのケースでこのラウンドを取得するための最も簡単な方法はDirectCastを削除し、代わりにEnumerable.Castを使用することです:

Dosomethingelse(dos.Cast(Of SharedLibrary.IAddinSettings)) 
+0

あなたが最も簡単な方法に言及している場合おかげで、そこにありますもう一つ?私はすでにenumerable.castについて何かを読んでおり、アドバイスはこれを避けることでした(実行時変換?) – Johan

+0

変換*は2つのリストタイプの非互換性のため実行時のものです。誰か* IAddinSettingsを実装していないIExecuteDoSomethingの実装を追加できました。 –

+0

ありがとう、キャストと動作するように見える、今コーディングを続けることができます... – Johan