Imports System.ComponentModel.Composition Imports System.ComponentModel.Composition.hosting Public Class MEFLoader Private importers As Dictionary(Of String, List(Of Object)) = New Dictionary(Of String, List(Of Object))() Public Overridable Function LoadByTag(Of T)(ByVal path As String, ByVal tag As String) As ICollection(Of T) Dim importer = GetImporter(Of T)(path) Return importer.LoadByMEF(path, tag) End Function Protected Function GetImporter(Of T)(ByVal path As String) As MEFImporter(Of T) Dim importerList = GetImporterList(path) Dim importer = importerList.OfType(Of MEFImporter(Of T))().FirstOrDefault() If importer Is Nothing Then importer = New MEFImporter(Of T)(path) importerList.Add(importer) End If Return importer End Function Protected Function GetImporterList(ByVal path As String) As List(Of Object) If importers.ContainsKey(path) = False Then importers.Add(path, New List(Of Object)()) Return importers(path) End Function Public Overridable Function LoadByType(Of T)(ByVal path As String) As ICollection(Of T) Return LoadByTag(Of T)(path, String.Empty) End Function End Class Public Interface IMetadata ReadOnly Property Name As String End Interface Public Class MEFImporter(Of T) Public Property [imports] As IEnumerable(Of Lazy(Of T, IMetadata)) Private Sub New() End Sub Public Sub New(ByVal path As String) Me.New() directoryCatalog = New DirectoryCatalog(path) End Sub Protected directoryCatalog As DirectoryCatalog = Nothing Protected Sub DoImport(ByVal path As String) Dim catalog = New AggregateCatalog() catalog.Catalogs.Add(directoryCatalog) Dim container As CompositionContainer = New CompositionContainer(catalog) container.ComposeParts(Me) End Sub Public Function LoadByMEF(ByVal path As String, ByVal name As String) As ICollection(Of T) Dim res = New List(Of T)() DoImport(path) For Each [module] As Lazy(Of T, IMetadata) In [imports] If [module].Metadata.Name = name OrElse String.IsNullOrEmpty(name) Then res.Add([module].Value) End If Next Return res End Function End Class