Files
2024-10-03 16:29:54 +02:00

83 lines
2.6 KiB
VB.net

Imports System.ComponentModel.Composition
Imports System.ComponentModel.Composition.Hosting
Imports Effector.Plugin.Interface
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)
<ImportMany(AllowRecomposition:=True)>
Public Property [imports] As IEnumerable(Of Lazy(Of T, IMetadata))
<Export>
Public Property SupervisorFunctions As IHost
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)
'catalog.Catalogs.Add(New AssemblyCatalog(System.Reflection.Assembly.GetCallingAssembly()))
catalog.Catalogs.Add(New AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()))
Dim container As CompositionContainer = New CompositionContainer(catalog)
Me.SupervisorFunctions = New SupervisorFunctions
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