MEF 和 DirectoryCatalog

9
有没有一种安全的方式可以使用DirectoryCatalog来处理目录不存在的情况?
以下是设置容器的代码示例:
    //Create an assembly catalog of the assemblies with exports
    var catalog = new AggregateCatalog(
        new AssemblyCatalog(Assembly.GetExecutingAssembly()),
        new AssemblyCatalog(Assembly.Load("My.Second.Assembly")),
        new DirectoryCatalog("Plugins", "*.dll"));

    //Create a composition container
    var container = new CompositionContainer(catalog);

但是如果目录不存在,会抛出异常,我希望忽略这个错误。


1
你为什么不能在设置“AggregateCatalog”之前检查目录是否存在呢? - Barry Wark
我想这样做,但是DirectoryCatalog内置了一些很好的逻辑来获取正确的路径(不仅仅是当前目录)。有人知道它使用了什么吗?Assembly.Location? - jonathanpeppers
我在下面的答案中进行了评论,但我也会在这里提到...你不应该仅依赖于检查目录是否存在。你应该考虑任何你想要处理的IOExceptions(例如,如果目录不存在,或者文件被锁定,或UAT等)。 - myermian
1个回答

9

如果抛出异常,则似乎不是这样。只需在运行MEF容器设置之前创建目录,就不会抛出错误。

根据文档:

路径必须是绝对的或相对于AppDomain.BaseDirectory

检查目录的伪代码:

    string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");

    //Check the directory exists
    if (!Directory.Exists(path))
    {
        Directory.CreateDirectory(path);
    }

    //Create an assembly catalog of the assemblies with exports
    var catalog = new AggregateCatalog(
        new AssemblyCatalog(Assembly.GetExecutingAssembly()),
        new AssemblyCatalog(Assembly.Load("My.Other.Assembly")),
        new DirectoryCatalog(path, "*.dll"));

    //Create a composition container
    _container = new CompositionContainer(catalog);  

请见上面我的评论。DirectoryCatalog使用什么方法来展开完整路径? - jonathanpeppers
它要么是绝对路径,要么是相对于System.AppDomain.BaseDirectory的路径。 - Jon Raynor
我已将您标记为答案。我在您的回答中更新了代码,以符合我的使用情况。 - jonathanpeppers
2
你不应该依赖于像 Directory.Exists(path) 这样的竞态条件检查。在该调用和下一次调用之间,目录可能不存在。相反,使用异常处理来捕获可能的异常并适当地处理它...请参见此答案:https://dev59.com/Jmox5IYBdhLWcg3wvWwy#9003962 - myermian
@m-y 你说得对,Directory.Exists(path) 是多余的。但是一旦它被移除了,仍然存在竞态条件。实际上的竞态条件是,在 Directory.CreateDirectory()new DirectoryCatalog() 之间,目录可能会被删除。尽管在这一点上让应用程序失败可能比尝试无限循环重新创建目录更好,如果它一直消失的话,那么你就有了一个不同的问题——程序的托管环境出现了问题 ^^. - binki
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接