Внедрение зависимостей и AppSettings

Допустим, я определяю класс реализации браузера для моего приложения:

class InternetExplorerBrowser : IBrowser {
    private readonly string executablePath = @"C:\Program Files\...\...\ie.exe";

    ...code that uses executablePath
}

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

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

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

Я мог бы решить обе проблемы, имеяexecutablePath передается через конструктор:

class InternetExplorerBrowser : IBrowser {
    private readonly string executablePath;

    public InternetExplorerBrowser(string executablePath) {
        this.executablePath = executablePath;
    }
}

но это вызовет проблемы в моемComposition Root (метод запуска, который будет выполнять все необходимые классы подключения), так как тогда этот метод должен знать, как подключать вещи и должен знать все эти маленькие данные настроек:

class CompositionRoot {
    public void Run() {
        ClassA classA = new ClassA();

        string ieSetting1 = "C:\asdapo\poka\poskdaposka.exe";
        string ieSetting2 = "IE_SETTING_ABC";
        string ieSetting3 = "lol.bmp";

        ClassB classB = new ClassB(ieSetting1);
        ClassC classC = new ClassC(B, ieSetting2, ieSetting3);

        ...
    }
}

который легко превратится в большой беспорядок.

Я мог бы перевернуть эту проблему, передав вместо этого интерфейс формы

interface IAppSettings {
    object GetData(string name);
}

для всех классов, которые нуждаются в каких-то настройках. Затем я мог бы реализовать это либо как обычный класс со всеми встроенными в него настройками, либо как класс, который считывает данные из файла XML, что-то в этом роде. При этом следует ли иметь общий экземпляр класса AppSettings для всей системы или иметь класс AppSettings, связанный с каждым классом, который может понадобиться? Это, конечно, кажется излишним. Кроме того, наличие всех настроек приложения в одном месте облегчает поиск и просмотр возможных изменений, которые необходимо выполнить при попытке перенести программу на разные платформы.

Как лучше всего подойти к этой общей ситуации?

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

А как насчет использованияIAppSettings со всеми его настройками в нем?

interface IAppSettings {
    string IE_ExecutablePath { get; }
    int IE_Version { get; }
    ...
}

Это позволило бы обеспечить безопасность типов во время компиляции. Если бы я увидел, что интерфейс / конкретные классы растут слишком сильно, я мог бы создать другие меньшие интерфейсы видаIMyClassXAppSettings, Будет ли это слишком тяжелым бременем для проектов среднего / большого размера?

Я также читал об АОП и его преимуществах, касающихся сквозных проблем (думаю, это одно из них). Разве он не может предложить решения этой проблемы? Может быть, пометить переменные, как это:

class InternetExplorerBrowser : IBrowser {
    [AppSetting] string executablePath;
    [AppSetting] int ieVersion;

    ...code that uses executablePath
}

Затем, при компиляции проекта у нас также была бы безопасность времени компиляции (если бы компилятор проверил, что мы фактически реализовали код, который вплетается в данные. Это, конечно, связало бы наш API с этим конкретным аспектом.

Ответы на вопрос(2)

Ваш ответ на вопрос