MEF и DirectoryCatalog

Има ли начин за безопасно използване на 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);

Но се хвърля изключение, ако директорията не съществува и бих искал да игнорирам тази грешка.


person jonathanpeppers    schedule 19.07.2011    source източник
comment
Има ли причина да не можете просто да проверите за съществуването на директорията, преди да настроите AggregateCatalog?   -  person Barry Wark    schedule 20.07.2011
comment
Бих, но изглежда има някаква хубава логика, вградена в DirectoryCatalog за получаване на правилния път (не просто текущата директория). Някой знае ли какво използва? Сглобяване. Местоположение?   -  person jonathanpeppers    schedule 20.07.2011
comment
Коментирах отговора по-долу, но ще го спомена и тук... не трябва да разчитате само на проверка за съществуването на директориите. Трябва да вземете предвид всички IOExceptions, които искате да обработите (т.е. ако директорията не съществува, или ако файловете са заключени, или UAT и т.н.)   -  person myermian    schedule 25.03.2014


Отговори (1)


Очевидно не, ако бъде хвърлено изключение. Просто създайте директорията, преди да стартирате настройката на контейнера MEF и тогава няма да се изведе грешка.

Според документацията:

Пътят трябва да е абсолютен или относителен към AppDomain.BaseDirectory.

PsuedoCode за извършване на проверка на директория:

    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);  
person Jon Raynor    schedule 19.07.2011
comment
Вижте коментара ми по-горе. Какъв метод използва DirectoryCatalog за разширяване на пълния път? - person jonathanpeppers; 20.07.2011
comment
Той е или абсолютен, или относителен към System.AppDomain.BaseDirectory. - person Jon Raynor; 20.07.2011
comment
Маркира те като отговор. Актуализирах вашия код във вашия отговор към това, което използвах. - person jonathanpeppers; 20.07.2011
comment
Никога не трябва да разчитате на проверка на състоянието на състезание като Directory.Exists(path). Между това повикване и следващото повикване директорията може да не съществува. Вместо това използвайте обработка на изключения, за да уловите възможно изключение и да го обработите по подходящ начин... вижте този отговор: stackoverflow.com/a/9003962/347172 - person myermian; 25.03.2014
comment
Directory.CreateDirectory ще се провали при малкия шанс директорията да бъде създадена между проверката за съществуване и извикването на createdirectory. Така че, да, трябва да има блок try catch около този код или някъде в стека на повикванията. - person Jon Raynor; 08.12.2014
comment
@JonRaynor Някога отделял ли си време да четеш документи и да правиш тестове с Directory.CreateDirectory? От документите: „Ако директорията вече съществува, този метод не създава нова директория, но връща обект DirectoryInfo за съществуващата директория.“ От тестване: извикването на Directory.CreateDirectory() не се проваля, ако директорията съществува. Цялата ти проверка е безсмислена. - person binki; 18.05.2016
comment
@m-y Прав си, че Directory.Exists(path) е излишно. Но след като това бъде премахнато, все още има условие за състезание. Действителното условие за състезание е, че директорията може да бъде изтрита между Directory.CreateDirectory() и new DirectoryCatalog(). Въпреки че просто оставянето на приложението да се провали в този момент може да е по-добре, отколкото евентуалното влизане в безкраен цикъл, опитвайки се да пресъздаде директорията, ако тя продължава да изчезва. Ако продължава да изчезва, имате различен проблем — проблем с хостинг средата на програмата ^^. - person binki; 18.05.2016