Как организовать большое количество констант пути файла / каталога - PullRequest
1 голос
/ 02 февраля 2012

У меня есть статический класс, в котором я храню большое количество относительных путей, которые используются в разных местах моего приложения.Это выглядит так:

static class FilePathConstants
{
    public const string FirstDirectory = "First";
    public const string FirstSecondDirectory = "First/Second";
    public const string FirstSecondThirdFileA = "First/Second/Third/FileA";
    public const string FirstSecondFourthFileB = "First/Second/Fourth/FileB";
    ... nearly 100 of similar members
}

Все они относятся к некоторому родительскому каталогу, местоположение которого я знаю только во время запуска программы.Мне нужно хранить их все вместе, потому что это позволяет мне легко контролировать, какие файлы используются моим приложением, и время от времени менять их расположение.

Однако даже если они организованы в алфавитном порядке и легко найти определенный путь, мне нужно иметь возможность изменять некоторые из них в зависимости от некоторых настроек.Допустим, есть настройка «bool SettingA», и когда я ее включаю, мне нужно изменить некоторые пути, чтобы использовать другой каталог или другое имя файла.

Проблема в том, что теперь я не могу использовать константы, мне приходится переписывать свой код в свойства или методы, чтобы я мог изменять пути к файлам во время выполнения.А вот где мой код становится намного больше по размеру и строгий порядок теперь выглядит безобразно.Есть ли способ, которым я могу сгруппировать их, чтобы это не смутило никого, кто использует этот код?Я не могу разбить их на отдельные классы, потому что трудно вспомнить, в каком классе вы можете хранить константу.Пока я группирую их по регионам, но у меня плохое предчувствие, что хранить более ста свойств в одном классе неправильно.

Редактировать:

Все каталоги и файлы, которые я объявляю в FilePathConstants, используются в большом количестве мест в приложении (каждый путь может использоваться несколько раз, принимая во внимание тот факт, что существует более ста путей - это большое количество).Я хотел бы сохранить интерфейс этого класса таким же или с минимальными изменениями для других классов, которые их используют.

Ответы [ 3 ]

1 голос
/ 02 февраля 2012

Используйте что-то вроде «индексного» файла для хранения путей к каталогам и загрузки его во время выполнения.

const string indexFilePath = @"C:\dirlist.txt";
IEnumerable<string> paths = File.ReadAllLines(indexFilePath);

Обновление

Я хотел бы предложить использовать косвенное обращение - класс "mapper". Вот как это должно выглядеть.

public enum FileSystemElement
{
    FirstDirectory,
    FirstSecondDirectory,
    FirstSecondThirdFileA,
    FirstSecondFourthFileB
}

public class FileSystemMapper
{
    private readonly string _rootDirectory;
    private readonly Dictionary<FileSystemElement, string> _fileElements;

    public FileSystemMapper(string rootDirectory, string fileName)
    {
        _rootDirectory = rootDirectory;
        string[] lines = File.ReadAllLines(fileName);
        _fileElements = lines.Select(ParsePair).ToDictionary(pair => pair.Key, pair => pair.Value);
    }

    public string GetPath(FileSystemElement element)
    {
        string relativePath;
        if (!_fileElements.TryGetValue(element, out relativePath))
        {
            throw new InvalidOperationException("Element not found");
        }

        string resultPath = Path.Combine(_rootDirectory, relativePath);
        return resultPath;
    }

    private static KeyValuePair<FileSystemElement, string> ParsePair(string line)
    {
        const string separator = "|";

        // File element alias | Path
        if (string.IsNullOrEmpty(line))
            throw new ArgumentException("Null or empty line", "line");                

        string[] components = line.Split(new[] { separator }, StringSplitOptions.RemoveEmptyEntries);
        if (components.Length != 2)
            throw new ArgumentException("Line has invalid format", "line");

        FileSystemElement element;
        bool parseResult = FileSystemElement.TryParse(components[0], out element);
        if (!parseResult)
            throw new ArgumentException("Invalid element name", "line");

        string path = components[1]; // for clarity
        return new KeyValuePair<FileSystemElement, string>(element, path);
    }

Пример клиента:

        FileSystemMapper fileSystemMapper = new FileSystemMapper(@"C:\root", @"C:\dirs.txt");
        string firstDirectory = fileSystemMapper.GetPath(FileSystemElement.FirstDirectory);
        string secondDirectory = fileSystemMapper.GetPath(FileSystemElement.FirstSecondDirectory);
        string secondThirdFile = fileSystemMapper.GetPath(FileSystemElement.FirstSecondThirdFileA);

Формат индексного файла: <Element name>|<Path><New Line>

Пример:

FirstDirectory|First
FirstSecondDirectory|First\Second
FirstSecondThirdFileA|First\Second\Third\FileA
FirstSecondFourthFileB|First\Second\Fourth\FileB
1 голос
/ 02 февраля 2012

возможно, вы могли бы использовать rowstructs

0 голосов
/ 02 февраля 2012

нельзя ли использовать ваши проекты Properties.Settings? он хранится в файле .config, поэтому его можно редактировать после развертывания

или просто не делайте их постоянными, затем вы можете редактировать их во время выполнения, но они возвращаются к исходным настройкам при следующем запуске.

или не делайте калибровку статической и не создавайте экземпляр каждый раз, когда вы его используете, затем изменяйте то, что необходимо, и отбрасывайте экземпляр по окончании.

...