DotNet · 2022年5月13日

自定义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)

最新电影,电视剧,尽在午夜剧场

电影电视剧午夜不寂寞