在MEF合成期间处理ReflectionTypeLoadException

Phi*_*son 23 c# mef

DirectoryCatalog在MEF中使用一个来满足我的应用程序中的导入.但是,目录中有时会出现模糊的程序集,导致ReflectionTypeLoadException我尝试编写目录时.

我知道我可以通过使用单独的目录或使用搜索过滤器DirectoryCatalog来解决它,但我想要一种更通用的方法来解决问题.有什么方法可以处理异常并允许组合继续吗?还是有另一个更通用的解决方案吗?

Dan*_*his 45

为了节省其他人编写他们自己的SafeDirectoryCatalog实现,这是我根据Wim Coenen的建议提出的:

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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1但我会在catch语句中添加一些日志记录.您可能还想捕获`BadImageFormatException`来忽略非.NET DLL. (6认同)
  • Steve,Directory.EnumerateFiles是.NET 4中的新功能,并且具有性能优势,因为当您请求它们时会返回条目,而不是像.GetFiles那样立即返回条目 (5认同)

Wim*_*nen 26

DirectoryCatalog已经有代码来捕获ReflectionTypeLoadException并忽略这些程序集.不幸的是,正如我所报告的那样,仅仅创建AssemblyCatalog将不会触发异常,因此代码不起作用.

该异常实际上是由第一次调用触发的AssemblyCatalog.Parts.

而不是使用DirectoryCatalog来自MEF,你必须自己做:

  • 扫描目录以查看程序集
  • 加载每个程序集并AssemblyCatalog为其创建一个
  • 调用AssemblyCatalog.Parts.ToArray()强制异常,并捕获它
  • 用a汇总所有好的目录 AggregateCatalog

  • 所以他们没有修复4.5中的错误 - 他们实际上让它变得更糟! (2认同)