none
IoC подход и конфигурационные файлы RRS feed

  • Общие обсуждения

  • Я использую IoC (DI) подход и обычно есть параметры, которые необходимо вычитать из конфигурационных файлов (строки подключения, какие-либо статические значения и т.д.) и которые используются в самом нижнем слое (слой БД и т.д.). Какой лучший способ это сделать?

    1. Читать напрямую из этого слоя, например:

    string sendGridApiKey = ConfigurationManager.AppSettings["SendGridApiKey"];

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

    2. Читать в верхнем слое (например, в веб-приложении) и потом перебрасывать это значение как параметр через все слои? Это также будет работать, но тогда все промежуточные слои будут загружены параметрами, которые их не используют (и таким образом мы также вносим зависимость этих слоёв от ненужных им параметров). Кроме того, разные реализации нижних библиотек могут требовать разные конфигурационные параметры, а интерфейс должен быть одинаковым для всех.
    21 февраля 2016 г. 0:37

Все ответы

  • Первый вариант конечно.

    "Это работает, но создаёт некоторые ограничения, например, для тестирования также нужно добавить эту строку в конфигурационный файл. Также получается, что этот слой зависит от правильно настроенного конфигурационного файла" - а как же по другому, не с воздуха же брать :).

    "Читать в верхнем слое (например, в веб-приложении) и потом перебрасывать это значение как параметр через все слои?" - не инверсия зависимостей, а мёртвая петля получаетя. Представьте себе, что вы слой хранения данных заменяете. И теперь у вас вместо СУРБД облачное хранилище, у которого нет такого понятия, как строка соединения БД. Тогда вам придётся менять реализацию интерфейса повыше, что само по себе нарушает принцип открытости/закрытости.


    Сделаем содержимое сообщества лучше, вместе!

    21 февраля 2016 г. 11:58
    Модератор
  • А книжечку про которую я вам говорил вы так и не прочли?

    Сделаем содержимое сообщества лучше, вместе!

    21 февраля 2016 г. 12:01
    Модератор
  • А книжечку про которую я вам говорил вы так и не прочли?

    Сделаем содержимое сообщества лучше, вместе!

    прочёл.

    видимо, упустил этот момент...

    21 февраля 2016 г. 15:58
  • не инверсия зависимостей, а мёртвая петля получаетя. Представьте себе, что вы слой хранения данных заменяете. И теперь у вас вместо СУРБД облачное хранилище, у которого нет такого понятия, как строка соединения БД. Тогда вам придётся менять реализацию интерфейса повыше, что само по себе нарушает принцип открытости/закрытости.


    на stackoverflow мне советуют третий вариант - вынести в параметры конструктора конкретной реализации нужные конфигурационные моменты. Например, для одной реализации ISendMail нужно 2 параметра - Login/password для SMTP, а для второй - только key. Итого имеем:

    public class SendMail1 : ISendMail
    {
         public SendMail1(string login, string password)
         {
         }
    }
    
    
    public class SendMail2 : ISendMail
    {
         public SendMail1(string key)
         {
         }
    }
    По-моему, это лучший подход. Во-первых, мы избавляемся от того, что конкретная реализация ISendMail зависит от конфигурационных файлов, во-вторых, "контракт" конкретной реализации чётко показывает, какие параметры ему нужны, в-третьих, мы избавляемся от необходимости дублировать конфигурационные настройки для рабочего приложения и для тестового.

    21 февраля 2016 г. 16:08