自定义DirectoryCatalog类处理ReflectionTypeLoadException
当我在MEF中使用DirectoryCatalog来实现对应用程序的扩展功能。使用的扩展类,可能会带入一些独立使用的引用DLL,这些DLL内不会存在扩展实现接口,此时在程序导入扩展模块时,会导致ReflectionTypeLoadException。
虽然可以通过一些命名约束并通过名称过滤的方法来忽略这些被扩展模块引用的DLL,但是并不是最佳的实现方法,所以希望有更优化的解决方案?
实现方法是通过自定义DirectoryCatalog类处理ReflectionTypeLoadException或其他类似的异常
下面是实现代码示例
C#
public class SafeDirectoryCatalog : ComposablePartCatalog
{
private readonly AggregateCatalog _catalog;
public SafeDirectoryCatalog(string directory)
{
var files = Directory.EnumerateFiles(directory,"*.dll", SearchOption.AllDirectories);
_catalog = new AggregateCatalog();
foreach (var file in files)
{
try
{
var asmCat = new AssemblyCatalog(file);
//Force MEF to load the plugin and figure out if there are any exports
// good assemblies will not throw the RTLE exception and can be added to the catalog
if (asmCat.Parts.ToList().Count > 0)
_catalog.Catalogs.Add(asmCat);
}
catch (ReflectionTypeLoadException)
{
}
catch (BadImageFormatException)
{
}
}
}
public override IQueryable<ComposablePartDefinition> Parts
{
get { return _catalog.Parts; }
}
}
VB.Net
Public Class SafeDirectoryCatalog
Inherits ComposablePartCatalog
Private ReadOnly Property _catalog As AggregateCatalog
Public Sub New(pDirectory As String)
Dim files = Directory.EnumerateFiles(pDirectory, "*.dll", SearchOption.TopDirectoryOnly)
_catalog = New AggregateCatalog()
For Each file In files
Try
Dim asmCat = New AssemblyCatalog(file)
If (asmCat.Parts.ToList().Count > 0) Then
_catalog.Catalogs.Add(asmCat)
End If
Catch ex As ReflectionTypeLoadException
Catch ex As BadImageFormatException
End Try
Next
End Sub
Public Overrides ReadOnly Property Parts As IQueryable(Of ComposablePartDefinition)
Get
Return _catalog.Parts
End Get
End Property
End Class
调用例子
Dim pDirectoryCatalog As New SafeDirectoryCatalog("Plugins") '增加对扩展目录的导入
pCatalogAggregate.Catalogs.Add(pDirectoryCatalog)
mPluginsMEFContainer = New CompositionContainer(pCatalogAggregate)