Здравствуйте, Tom, Вы писали:
IQ>>Звучит эпически, а как быть со stateless объектами в которых одна логика и нет состояния? Для чего им DI, если потенциальное время их жизни — от старта системы до самого ее финиша?
Tom>Звучит не эпически а логично. Statefull или Stateless абсолютно никак не влияет на то надо ли обьект инжектить. Единственное на что это влияет — на время жизни обьекта. Если он Stateless — его смело можно делать singleton-ом. Что касается Statefull то надо разбираться что за стейт и кому он принадлежит. А у вас в голове каша, вы смешали разные понятия — State-а, и DI. На вопрос для чего — уже обьяснял, для того что бы иметь возможность подменять в тестах, для того что бы сделать зависимость явной.
Опять эти тесты... несовершенная технология тестирования в ответе за уничтожение мозгов огромного количества разработчиков. Сегодня уже есть технологии позволяющие не ломать архитектуру исходя из потребностей тестирования.
Если бы вы прочитали сам пост, то несомненно увидели бы, что я описываю ситуацию, когда тесты в проекте — это несбыточная фантазия.
IQ>>Забавно ))) вот например время жизни db entity определяется оно как правило контекстом внутри одного метода от загрузки из БД до сохранения в БД. Вот например есть ворох статических хелперных методов не имеющих состояния. Вот например есть целые сервисы, зависимость от которых и жизни которых определяется контекстом бизнес операции т.к. сильно зависит от бизнес логики... Tom>Спросить то чего хотел. И ещё раз уточню, забавно выглядит тут ваша позиция неофита. Могу спорить вы возрастной программист лет после 40-ка которые просто не смог в DI. И уже никогда не сможет.
Я в посте все написал — я лично не встречал проектов, где DI был обоснованно использован. Увы мне, увы моей конторе. Мы клепаем бизнес логику, тоннами. Может где-то оно иначе, мой пост не против DI, а против его использования в религиозных целях.
IQ>>Мне кажется или ваша позиция больше связана с вопросами веры, чем с вопросами разработки ПО? Tom>Вам кажется. Моя позиция связана с принципами и опытом разработки mission critical систем работающих 24/7 и распространяющихся по схеме PaaS. Качество для нас критически важно. Покрытие тестами для нас критически важно.
Спрошу прямо — вы на каком курсе института?
Tom>>>2. Использование DI позволяет тебе чётко определять все зависимости объекта, зависимости становятся явными и получает их обьект обычно в конструкторе. Иными словами мне НЕ нужно лазить по коду объекта что бы понять а от чего ещё он зависит. Достаточно глянуть в конструктор и всё становится понятным.
Tom>>>3. При тотальном использовании DI во всём проекте во всём проекте используется один и тот же стандартных подход. Такой код читать просто и понятно. А вот обратный случай когда вот тут вот мы сделаем new, а вот там вот вызовем статический метод а вот это вот мы заинжектим потому что оно — это сервис (а что такое сервис никто не знает). Это точно бред.
IQ>> У меня полно опыта в области DI. Я отхреначивал DI нафиг уже в трех проектах потому как с ним архитектура типа big ball of mud становиться абсолютно неподдерживаемой.
Tom>С чем вас и поздравляю. Отхреначивайте дальше. И к архитектуре DI не имеет никакого отношения. DI это маленькая частная практика наряду с кучей других практик которые необходимы для того что бы писать качественный код. А то что вы делает называется "макароны"
Если бы вы прочитали пост, то сообразили, что именно про это там и написано И собственно проблема о которой я заявляю в том, что "маленькая частная практика DI" в силу своей формальности, доминирует над всеми другими практиками. Что использование DI не делает архитектуру автоматически хорошей А вот г...код делает на порядок более многословным и сложным.
PS И к архитектуре DI не имеет никакого отношения.
Т.е. по вашему использование механизмов DI никак не влияет на архитектуру системы?
Здравствуйте, Tom, Вы писали:
Tom>Здравствуйте, IQuerist, Вы писали:
IQ>>Здравствуйте, Tom, Вы писали:
IQ>>>>Имхо главного не написано — маниакальная страсть к IOC навязываемая ранним внедрением DI провоцирует нарушение всех принципов SOLID. Tom>>>Вы бы с SOLID разобрались и не писали чушь. Расскажите мне как DI у нас портит S или I я уже не говорю про D
IQ>>Вы бы сам пост, таки почитали... Tom>Я сам пост читал, в отличии от вас. Вам зажали конкретный вопрос, что именно и как именно из SOLID нарушает DI. Вы слились...
Ну так вы вопросы не зажимайте... и на них таки ответят. Или уже ответили в тексте поста.
>>>Вы слились.
Здравствуйте, Tom, Вы писали:
Tom>·>Куча вредных антипаттернов, которые легко размазать по всему проекту, а обычно достаточно одного единственного constructor injection. И вычищать потом это — замучаешься. Tom>Давай по конкретнее. Хоть один анти паттерн покажи мне и опиши в чём состоит проблема. SL. В подавляющем числе случаев он не нужен. Проблема — он делает зависимости неявными.
методы-инициализаторы и property injection. Проблема — добавляет в объект опасное состояние "создан, но не очень-то ещё создан".
Магические строки. Ничем не лучше магических чисел.
Сканирование сборок. В подавляющем числе случаев он не нужен. Доставляет столько удовольствия исследовать что куда залетело и почему. Притом это можно исследовать только на запущенной системе в данном (часто prod) окружении.
Циклические зависимости. С DI+CI сделать цикл невозможно. Заставляет аккуратнее подходить к архитектуре приложения, а не всякие lazy/PI, которые тебе циклы создадут на ура.Tom>·>выглядит ничуть не хуже. Tom>Выглядит хуже. И создаёт конкретные проблемы в вполне конкретных случаях. Я больше скажу, с управлением временем жизни обьектов руками есть большие проблемы даже на теоретическом уровне.
Если это невозможно на теоретическом уровне, то как контейнер это будет разруливать?
Tom>Вот тебе прмиер. Есть обьект IFoo. Ну или IPlugin для наглядности. Есть пара его реализаций, одна из них использует unmanaget ресурсы и требует реализации IDisposable а другая нет. Кроме как калечного решения в виде наследованияч IPlugin от IDisposable для ручного управления зависимостями я не вижу.
Не понял. Давай более конкретный пример. Вот код:
var foo = fooProvider.giveMeFoo();
doSomethingWith(foo);
Если какие-то из IFoo могут быть disposable ты в данном месте обязан предполагать худшее и всегда освобождать foo, т.к. ты не знаешь какой из IFoo провайдер тебе выдаст. Поэтому будь добр оберни:
Если это известно в инфраструктурном коде, так и пиши в wiring модуле:
if(useDatabase)
{
using(var foo = new DatabaseFoo(connectionString))
{
doBusinessLogicWith(foo);
}
}
else
{
var foo = new InMemoryFoo();
doBusinessLogicWith(foo);
}
и спаси IFoo от leaking abstractions.
Tom>·>Единственное для чего эти контейнеры могут быть хороши это всякое Assembly Scanning, но реально проектов, где это необходимо — очень мало. Tom>Контейнеры много чего могут но это бесполезно обьяснять человеку у которого в голове установка что они зло.
Но это всё не надо использовать. Контейнеры можно использовать для каких-то сложных случаев, только в довольно маленьком чётко отделённом контексте, в плагинном менеджере каком-нибудь например. Но пихать везде — антипаттерн.
Tom>·>Зато полная поддержка компилятора и IDE. А неудобно только с непривычки. Tom>new это огромные трудности при написании тестов. Я про Integration тесты. Tom>Руками собирать всё дерево зависимостей? Вопрос нахера, если я 2-мя движениями мышки могу в тесте подменить любую зависимость.
Нет, просто пишешь классы-модули, которые делают wiring тестируемых поддеревьев зависимостей. И тестируешь именно их. Иначе интеграционные тесты тестируют тестовый wiring.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
IQ>Опять эти тесты... несовершенная технология тестирования в ответе за уничтожение мозгов огромного количества разработчиков. Сегодня уже есть технологии позволяющие не ломать архитектуру исходя из потребностей тестирования.
Ну так давайте с тестов и начнём. Расскажите нам про эту чудо технологию (надеюсь не Typemock и не Microsoft Shim?)
А ещё лучше, просветите нас, покажите ваши тесты.
IQ>Если бы вы прочитали сам пост, то несомненно увидели бы, что я описываю ситуацию, когда тесты в проекте — это несбыточная фантазия.
??? Тесты, фантазия???? Без коментариев.
IQ>>>Забавно ))) вот например время жизни db entity определяется оно как правило контекстом внутри одного метода от загрузки из БД до сохранения в БД. Вот например есть ворох статических хелперных методов не имеющих состояния. Вот например есть целые сервисы, зависимость от которых и жизни которых определяется контекстом бизнес операции т.к. сильно зависит от бизнес логики... Tom>>Спросить то чего хотел. И ещё раз уточню, забавно выглядит тут ваша позиция неофита. Могу спорить вы возрастной программист лет после 40-ка которые просто не смог в DI. И уже никогда не сможет.
IQ>Я в посте все написал — я лично не встречал проектов, где DI был обоснованно использован. Увы мне, увы моей конторе. Мы клепаем бизнес логику, тоннами. Может где-то оно иначе, мой пост не против DI, а против его использования в религиозных целях.
IQ>>>Мне кажется или ваша позиция больше связана с вопросами веры, чем с вопросами разработки ПО? Tom>>Вам кажется. Моя позиция связана с принципами и опытом разработки mission critical систем работающих 24/7 и распространяющихся по схеме PaaS. Качество для нас критически важно. Покрытие тестами для нас критически важно.
IQ>Спрошу прямо — вы на каком курсе института?
Спросите прямо сколько мне лет. Я не стесняюсь, мне будет 37 зимой.
IQ>Т.е. по вашему использование механизмов DI никак не влияет на архитектуру системы?
DI относится к реализации а не архитектуре. DI слишком низкоуровневая абстракция что бы её относить к архитектуре.
Здравствуйте, IQuerist, Вы писали:
IQ>Здравствуйте, Tom, Вы писали:
Tom>>Здравствуйте, IQuerist, Вы писали:
IQ>>>Здравствуйте, Tom, Вы писали:
IQ>>>>>Имхо главного не написано — маниакальная страсть к IOC навязываемая ранним внедрением DI провоцирует нарушение всех принципов SOLID. Tom>>>>Вы бы с SOLID разобрались и не писали чушь. Расскажите мне как DI у нас портит S или I я уже не говорю про D
IQ>>>Вы бы сам пост, таки почитали... Tom>>Я сам пост читал, в отличии от вас. Вам зажали конкретный вопрос, что именно и как именно из SOLID нарушает DI. Вы слились...
IQ>Ну так вы вопросы не зажимайте... и на них таки ответят. Или уже ответили в тексте поста.
Вы ответите на вопрос, что вы имели ввиду когда написали "маниакальная страсть к IOC навязываемая ранним внедрением DI провоцирует нарушение всех принципов SOLID". Поясните мне недогадливому на примерах, какие именно принципы из SOLID и как именно по вашему нарушаются.
>>>>Вы слились. IQ> вы нам тут устраиваете сеанс унитазной магии?
Мда. Оставлю ьез коментариев.
Здравствуйте, Tom, Вы писали:
IQ>>Опять эти тесты... несовершенная технология тестирования в ответе за уничтожение мозгов огромного количества разработчиков. Сегодня уже есть технологии позволяющие не ломать архитектуру исходя из потребностей тестирования. Tom>Ну так давайте с тестов и начнём. Расскажите нам про эту чудо технологию (надеюсь не Typemock и не Microsoft Shim?) Tom>А ещё лучше, просветите нас, покажите ваши тесты.
Это становиться смешно, вы пост читали? Нет никаких тестов проекты с наивным DI до них, как правило не доживают.
IQ>>Если бы вы прочитали сам пост, то несомненно увидели бы, что я описываю ситуацию, когда тесты в проекте — это несбыточная фантазия. Tom>??? Тесты, фантазия???? Без коментариев.
Если бы вы прочитали пост, то обошлись бы без фантазий там русским по белому написано — использование DI в конкретном проекте часто обосновывают исключительно потребностью создания юнит тестов, которых конкретный проект никогда не дождется.
IQ>>Спрошу прямо — вы на каком курсе института? Tom>Спросите прямо сколько мне лет. Я не стесняюсь, мне будет 37 зимой.
И на каком вы курсе института в 37 лет зимой?
Вы выдали столько "маркетинговово базза", сколько я слышал только от студентов.
IQ>>Т.е. по вашему использование механизмов DI никак не влияет на архитектуру системы? Tom>DI относится к реализации а не архитектуре. DI слишком низкоуровневая абстракция что бы её относить к архитектуре.
Справедливо К сожалению я слишком часто наблюдаю ситуацию, когда архитектуру big ball of mud пытаются облагородить используя DI (о том и пост). И возникает закономерный вопрос — свелось бы развитие проекта к big ball of mud без маниакальной потребности внедрения DI на самых ранних стадиях или таки нет...
Re[10]: О "наивном" DI и об архитектурном бессилии
Здравствуйте, Tom, Вы писали:
IQ>>Ну так вы вопросы не зажимайте... и на них таки ответят. Или уже ответили в тексте поста. Tom>Вы ответите на вопрос, что вы имели ввиду когда написали "маниакальная страсть к IOC навязываемая ранним внедрением DI провоцирует нарушение всех принципов SOLID". Поясните мне недогадливому на примерах, какие именно принципы из SOLID и как именно по вашему нарушаются.
Была такая идея, но в целом все основные проблемы сводились к тому, что в качестве сервисов используются ну очень низкоуровневые конкретные реализации, как правило это DAL хелперы. В статье это уже показано, так что мне это все показалось избыточным.
IQ>>>Опять эти тесты... несовершенная технология тестирования в ответе за уничтожение мозгов огромного количества разработчиков. Сегодня уже есть технологии позволяющие не ломать архитектуру исходя из потребностей тестирования. Tom>>Ну так давайте с тестов и начнём. Расскажите нам про эту чудо технологию (надеюсь не Typemock и не Microsoft Shim?) Tom>>А ещё лучше, просветите нас, покажите ваши тесты.
IQ> Это становиться смешно, вы пост читали? Нет никаких тестов проекты с наивным DI до них, как правило не доживают.
У вас не доживают, у всех остальных проблем нету. Покажите мне ВАШИ тесты которые делаете ВЫ в ваших правильных проектах.
Расскажите и научите как ВЫ делаете Правильно.
IQ>>>Если бы вы прочитали сам пост, то несомненно увидели бы, что я описываю ситуацию, когда тесты в проекте — это несбыточная фантазия. Tom>>??? Тесты, фантазия???? Без коментариев.
IQ>Если бы вы прочитали пост, то обошлись бы без фантазий там русским по белому написано — использование DI в конкретном проекте часто обосновывают исключительно потребностью создания юнит тестов, которых конкретный проект никогда не дождется.
IQ>>>Спрошу прямо — вы на каком курсе института? Tom>>Спросите прямо сколько мне лет. Я не стесняюсь, мне будет 37 зимой.
IQ>И на каком вы курсе института в 37 лет зимой? IQ>Вы выдали столько "маркетинговово базза", сколько я слышал только от студентов.
Я начал программировать когда мне не было ещё 10 лет. А работать лет в 20 по специальности если вас интересует мой опыт.
И всё это время я учусь ибо в нашей профессии это необходимо что бы оставаться профессионалом.
IQ>>>Т.е. по вашему использование механизмов DI никак не влияет на архитектуру системы? IQ>Справедливо К сожалению я слишком часто наблюдаю ситуацию, когда архитектуру big ball of mud пытаются облагородить используя DI (о том и пост). И возникает закономерный вопрос — свелось бы развитие проекта к big ball of mud без маниакальной потребности внедрения DI на самых ранних стадиях или таки нет...
К сожалению у вас такая каша в голове что ни что такое архитектура, ни что такое DI ни что такое контейнеры для чего они нужны и как их правильно использовать, ни что такое State и как его правильно использовать вы не знаете. Но при этом НЕ спрашиваете вопросы а уверенно утверждаете что DI это зло. А на вопросы рассказать как с вашей точки зрения делать правильно вы тихочечно сливаетесь... Ваш "союзник" рядом хоть по делу спрашивает. А у вас всё сопли из носа надуваются.
·>SL. В подавляющем числе случаев он не нужен. Проблема — он делает зависимости неявными.
? Что такое SL?
·>[методы-инициализаторы и property injection. Проблема — добавляет в объект опасное состояние "создан, но не очень-то ещё создан".
Абсолютно согласен, зло злейшее. В 99% только Constructor Injection. Правда есть пару случаев когда из за "чужёго кривого дизайна" приходится использовать property injection но это исключение.
·>Магические строки. Ничем не лучше магических чисел.
Давай с самого начала, есть ощущение что ты не понимаешь откуда там при регистрации взялись строки. Есть 2 принципиально разных случая. Случай 1 — я хочу что бы в контейнере была зарегистрирована только одна реализация интерфейса X. В этом случае никаких строк ненадо, обычная регистрация. Если я хочу переопределить предыдущую регистрацию, например в тесте то я так же выполняю обычную регистрацию без каких либо имён ака строк. Но что делать если:
a) Я хочу зарегистрировать в контейнере 2 реализации одного и того же интерфейса. Как сказать контейнеру что я хочу не "перезаписать" предыдущую регистрацию а сделать их две. И более того, как эти 2 регистрации идентифицировать, как потом если вдруг надо зарезолвить конкретную регистарцию. Ведь иногда мне могут понадобиться все регистрации интерфейса аля IEnumerable<IFoo> а иногда нужно взять конкретную (таких случаев вагон). Вот для этого и придумали имена. Да конечно надо как то регистрации отличать друг от друга и ничего проще строк тут нету. Что бы эти строки перестали быть магическими — вынеси их в константу и используй эту константу как при регистарции так и при резолве.
·>Сканирование сборок. В подавляющем числе случаев он не нужен. Доставляет столько удовольствия исследовать что куда залетело и почему. Притом это можно исследовать только на запущенной системе в данном (часто prod) окружении.
Ничего не понимаю что куда залетело. В общем случае фича которая называется auto wire работает прекрасно. Регистрируешь только то что отличается от принятых в контейнере конвенций.
·>Циклические зависимости. С DI+CI сделать цикл невозможно. Заставляет аккуратнее подходить к архитектуре приложения, а не всякие lazy/PI, которые тебе циклы создадут на ура.
Эммм а где антипаттерн? И причём тут контейнеры с DI. Если у тебя циклические зависимости то это проблема не контейнера а проблема твоего дизайна. Но даже в этом случае контейнер может подставить тебе плечо, ты можешь резолвить Lazy<T> и фактически резолв будет сделан в момент использования.
Tom>>Вот тебе прмиер. Есть обьект IFoo. Ну или IPlugin для наглядности. Есть пара его реализаций, одна из них использует unmanaget ресурсы и требует реализации IDisposable а другая нет. Кроме как калечного решения в виде наследованияч IPlugin от IDisposable для ручного управления зависимостями я не вижу.
·>Не понял. Давай более конкретный пример. Вот код:
На стадии проектирования интерфейса и своей реализации интерфейса ты НЕ знаешь будут ли другие реализации которым может потребоваться очистка ресурсов. Это основная идея. В случае исполдьзования контейнера, обычно, на запрос создаётся так называемый child container который разрушается при окончании обработки запроса и который при разрушении вызовет Dispose у обьектов которые были в нём зарезолвлены. Причём он вызовет Dispose естественно вне зависимости от того унаследован интерфейс от IDsiposable или нет. В случае когда у тебя контейнера нет тебе надо либо самому писать такой функционал но это не возможно так как без контейнера нет единственного класса который контролирует время жизни всех обьектов. Либо наследовать интерфейс от IDisposable в тех местах где ты предпологаешь в реализациях может понадобится очистка ресурсов, но это жутко криво ибо во первых ты по сути не должен знать и не знаешь где очистка может понадобится а во вторых сам факт наследования от IDisposable это ад адский.
Tom>>·>Единственное для чего эти контейнеры могут быть хороши это всякое Assembly Scanning, но реально проектов, где это необходимо — очень мало. Tom>>Контейнеры много чего могут но это бесполезно обьяснять человеку у которого в голове установка что они зло. ·>Но это всё не надо использовать. Контейнеры можно использовать для каких-то сложных случаев, только в довольно маленьком чётко отделённом контексте, в плагинном менеджере каком-нибудь например. Но пихать везде — антипаттерн.
Так, то что это вдруг антипатотерн — это придумал ты. Основная масса современных разработчиков с этим не согласна
Tom>>·>Зато полная поддержка компилятора и IDE. А неудобно только с непривычки. Tom>>new это огромные трудности при написании тестов. Я про Integration тесты. Tom>>Руками собирать всё дерево зависимостей? Вопрос нахера, если я 2-мя движениями мышки могу в тесте подменить любую зависимость. ·>Нет, просто пишешь классы-модули, которые делают wiring тестируемых поддеревьев зависимостей. И тестируешь именно их. Иначе интеграционные тесты тестируют тестовый wiring.
О чём и речь, без контейнера тебе надо собирать деревья зависимостей руками. Зачем это делать если это умеет делать контейнер.
Народная мудрось
всем все никому ничего(с).
Re[11]: О "наивном" DI и об архитектурном бессилии
Здравствуйте, IQuerist, Вы писали:
IQ>Здравствуйте, Tom, Вы писали:
IQ>>>Ну так вы вопросы не зажимайте... и на них таки ответят. Или уже ответили в тексте поста. Tom>>Вы ответите на вопрос, что вы имели ввиду когда написали "маниакальная страсть к IOC навязываемая ранним внедрением DI провоцирует нарушение всех принципов SOLID". Поясните мне недогадливому на примерах, какие именно принципы из SOLID и как именно по вашему нарушаются.
IQ>Была такая идея, но в целом все основные проблемы сводились к тому, что в качестве сервисов используются ну очень низкоуровневые конкретные реализации, как правило это DAL хелперы. В статье это уже показано, так что мне это все показалось избыточным.
Ключевое слово вам показалось.
Тесты когда свои покажешь?
Народная мудрось
всем все никому ничего(с).
Re[12]: О "наивном" DI и об архитектурном бессилии
Здравствуйте, Tom, Вы писали:
Tom>Здравствуйте, IQuerist, Вы писали:
IQ>>Здравствуйте, Tom, Вы писали:
IQ>>>>Ну так вы вопросы не зажимайте... и на них таки ответят. Или уже ответили в тексте поста. Tom>>>Вы ответите на вопрос, что вы имели ввиду когда написали "маниакальная страсть к IOC навязываемая ранним внедрением DI провоцирует нарушение всех принципов SOLID". Поясните мне недогадливому на примерах, какие именно принципы из SOLID и как именно по вашему нарушаются.
IQ>>Была такая идея, но в целом все основные проблемы сводились к тому, что в качестве сервисов используются ну очень низкоуровневые конкретные реализации, как правило это DAL хелперы. В статье это уже показано, так что мне это все показалось избыточным. Tom>Ключевое слово вам показалось.
Так и топик мой Вам кажется иначе? Запостите свой.
Здравствуйте, Tom, Вы писали:
IQ>>>>Опять эти тесты... несовершенная технология тестирования в ответе за уничтожение мозгов огромного количества разработчиков. Сегодня уже есть технологии позволяющие не ломать архитектуру исходя из потребностей тестирования. Tom>>>Ну так давайте с тестов и начнём. Расскажите нам про эту чудо технологию (надеюсь не Typemock и не Microsoft Shim?) Tom>>>А ещё лучше, просветите нас, покажите ваши тесты.
IQ>> Это становиться смешно, вы пост читали? Нет никаких тестов проекты с наивным DI до них, как правило не доживают. Tom>У вас не доживают, у всех остальных проблем нету.
К 37 то годочкам, уж пора бы отучиться говорить за всех...
Tom>Расскажите и научите как ВЫ делаете Правильно.
Если бы вы прочитали пост, то поняли бы, что он не том, как делать правильно. А о том, как часто делают неправильно.
IQ>>И на каком вы курсе института в 37 лет зимой? IQ>>Вы выдали столько "маркетинговово базза", сколько я слышал только от студентов. Tom>Я начал программировать когда мне не было ещё 10 лет. А работать лет в 20 по специальности если вас интересует мой опыт.
Абсолютно не интересует. Опыт часто видно по задаваемым вопросам.
Tom>И всё это время я учусь ибо в нашей профессии это необходимо что бы оставаться профессионалом.
Вот никогда не понимал людей, которые врут наполовину
Tom>К сожалению у вас такая каша в голове что ни что такое архитектура, ни что такое DI ни что такое контейнеры для чего они нужны и как их правильно использовать, ни что такое State и как его правильно использовать вы не знаете. Но при этом НЕ спрашиваете вопросы а уверенно утверждаете что DI это зло.
Ну прочитайте уже пост! Я нигде не утверждаю что DI это зло. Наоборот, специально раз пять написал обратное.
IQ>>> Это становиться смешно, вы пост читали? Нет никаких тестов проекты с наивным DI до них, как правило не доживают. Tom>>У вас не доживают, у всех остальных проблем нету. IQ>К 37 то годочкам, уж пора бы отучиться говорить за всех...
Я говорю за пару сотен разработчиков и несколько десятков проектов с которыми я знаком.
Tom>>Расскажите и научите как ВЫ делаете Правильно. IQ>Если бы вы прочитали пост, то поняли бы, что он не том, как делать правильно. А о том, как часто делают неправильно.
Прочитал. Не понял. Поясните.
IQ>>>И на каком вы курсе института в 37 лет зимой? IQ>>>Вы выдали столько "маркетинговово базза", сколько я слышал только от студентов. Tom>>Я начал программировать когда мне не было ещё 10 лет. А работать лет в 20 по специальности если вас интересует мой опыт.
IQ>Абсолютно не интересует. Опыт часто видно по задаваемым вопросам. Tom>>И всё это время я учусь ибо в нашей профессии это необходимо что бы оставаться профессионалом. IQ>Вот никогда не понимал людей, которые врут наполовину
Можно по подробнее где я вру
IQ>Ну прочитайте уже пост! Я нигде не утверждаю что DI это зло. Наоборот, специально раз пять написал обратное.
У вас DI какой то очень странный. Какой то избирательный. Вы так и не пояснили критерии как определить что надо DI а что не надо и главное почему не надо и какие проблемы это несёт.
Народная мудрось
всем все никому ничего(с).
Re[13]: О "наивном" DI и об архитектурном бессилии
IQ>Так и топик мой Вам кажется иначе? Запостите свой.
Топик ваш в котором вы не отвечаете за слова. Сказали что DI то то нарушает а рссказать нам что и почему именно не можете. Сказал бы что погорячился и проехали бы но нет, упираемся...
Народная мудрось
всем все никому ничего(с).
Re[10]: О "наивном" DI и об архитектурном бессилии
Здравствуйте, Tom, Вы писали:
Tom>·>SL. В подавляющем числе случаев он не нужен. Проблема — он делает зависимости неявными. Tom>? Что такое SL?
Service Locator.
Tom>Абсолютно согласен, зло злейшее. В 99% только Constructor Injection. Правда есть пару случаев когда из за "чужёго кривого дизайна" приходится использовать property injection но это исключение.
Но вот добрый контейнер легко и непринуждённо позволяет это пихать куда угодно в любых количествах.
Tom>Да конечно надо как то регистрации отличать друг от друга и ничего проще строк тут нету. Что бы эти строки перестали быть магическими — вынеси их в константу и используй эту константу как при регистарции так и при резолве.
А зачем тебе их по строкам отличать? Зачем их вообще отличать? Есть две ситуации.
Первая cитуация, у тебя действительно два инстанса и ты разные инстансы используешь в разных частях программы с разными целями. Ну например, DbConnection для основной БД и для отдельной БД для аудита, например. В этом случае тебе строки не нужны. В случае ручного связывания у тебя вместо строк это будет именем поля или локальной переменной.
Вторая ситуация, у тебя действительно несколько инстансов и их нужно как-то определять в рантайме в зависимости от каких-то данных. Ну например, найти инстанс какого-нибудь класса по фрагменту URL. В этом случае следует использовать не "ничего проще строк нету", а соответсвующий бизнес-требованиям тип — UrlFragment, enum, етс. Пихать везде строки — плохой стиль.
Tom>·>Сканирование сборок. В подавляющем числе случаев он не нужен. Доставляет столько удовольствия исследовать что куда залетело и почему. Притом это можно исследовать только на запущенной системе в данном (часто prod) окружении. Tom>Ничего не понимаю что куда залетело. В общем случае фича которая называется auto wire работает прекрасно. Регистрируешь только то что отличается от принятых в контейнере конвенций.
Я о http://www.lightinject.net/#assembly-scanning , а ты о чём?
Tom>·>Циклические зависимости. С DI+CI сделать цикл невозможно. Заставляет аккуратнее подходить к архитектуре приложения, а не всякие lazy/PI, которые тебе циклы создадут на ура. Tom>Эммм а где антипаттерн? И причём тут контейнеры с DI. Если у тебя циклические зависимости то это проблема не контейнера а проблема твоего дизайна. Но даже в этом случае контейнер может подставить тебе плечо, ты можешь резолвить Lazy<T> и фактически резолв будет сделан в момент использования.
Циклические зависимости делать не надо. Никогда. А если это действительно неизбежно — это должно быть сложно и сразу явно видно. Ты можешь случайно добавить незаметив, а контейнер тебе всё сам свяжет и не пикнет, втихую добавив +100 к техническому долгу. А потом эту вязанку развязывать.
Tom>На стадии проектирования интерфейса и своей реализации интерфейса ты НЕ знаешь будут ли другие реализации которым может потребоваться очистка ресурсов. Это основная идея. В случае исполдьзования контейнера, обычно, на запрос создаётся так называемый child container который разрушается при окончании обработки запроса и который при разрушении вызовет Dispose у обьектов которые были в нём зарезолвлены. Причём он вызовет Dispose естественно вне зависимости от того унаследован интерфейс от IDsiposable или нет. В случае когда у тебя контейнера нет тебе надо либо самому писать такой функционал но это не возможно так как без контейнера нет единственного класса который контролирует время жизни всех обьектов. Либо наследовать интерфейс от IDisposable в тех местах где ты предпологаешь в реализациях может понадобится очистка ресурсов, но это жутко криво ибо во первых ты по сути не должен знать и не знаешь где очистка может понадобится а во вторых сам факт наследования от IDisposable это ад адский. public class RequestModule и пусть он и управляет временем жизни создаваемых им IDisposable-ы ровно так как надо, а не универсальный всемогутер, который делает какую-то неявную магию.
Tom>>>Контейнеры много чего могут но это бесполезно обьяснять человеку у которого в голове установка что они зло. Tom>·>Но это всё не надо использовать. Контейнеры можно использовать для каких-то сложных случаев, только в довольно маленьком чётко отделённом контексте, в плагинном менеджере каком-нибудь например. Но пихать везде — антипаттерн. Tom>Так, то что это вдруг антипатотерн — это придумал ты. Основная масса современных разработчиков с этим не согласна
Я знаю. Сам таким был.
Потом попал в компанию, где история развития была такая: "что попало как попало" -> "монстр Spring Framework" -> "модный Guice" -> "DI, plain Java code". По началу тоже возмущался отстутсвием "современного" контейнера, а потом осенило.
Tom>·>Нет, просто пишешь классы-модули, которые делают wiring тестируемых поддеревьев зависимостей. И тестируешь именно их. Иначе интеграционные тесты тестируют тестовый wiring. Tom>О чём и речь, без контейнера тебе надо собирать деревья зависимостей руками. Зачем это делать если это умеет делать контейнер.
Дерево зависимостей довольно сложная, но важная вещь. Оно не только является некого рода документом, описывающим высокоуровневую архитектуру, но и сдерживающим фактором говнокодинга. Если у тебя это самое дерево руками получается делать плохо, слишком сложно, непонятно, значит ты делаешь что-то не то, остановись, подумай — сделай проще. А контейнер эту всю сложность прячет под коврик и через какое-то время кроме как автоматически это дерево не строится. Контроль над сложностью потерян, значит без бутылки человек уже не разберётся что куда откуда.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[14]: О "наивном" DI и об архитектурном бессилии
Здравствуйте, Tom, Вы писали:
IQ>>Так и топик мой Вам кажется иначе? Запостите свой. Tom>Топик ваш в котором вы не отвечаете за слова.
Нда... я с универа такой предьявы не слышал.
Tom>Сказали что DI то то нарушает а рссказать нам что и почему именно не можете. Сказал бы что погорячился и проехали бы но нет, упираемся...
Погорячился? Мне стабильно приходится отхреначивать из проектов "наивный DI", который только мешает.
Читайте пост. Не согласны — пишите свой.
Re[10]: О "наивном" DI и об архитектурном бессилии
Здравствуйте, Tom, Вы писали:
IQ>>К 37 то годочкам, уж пора бы отучиться говорить за всех... Tom>Я говорю за пару сотен разработчиков и несколько десятков проектов с которыми я знаком.
Очевидно я говорю за миллионы остальных , чем особо не хвастаю.
Tom>>>Расскажите и научите как ВЫ делаете Правильно. IQ>>Если бы вы прочитали пост, то поняли бы, что он не том, как делать правильно. А о том, как часто делают неправильно. Tom>Прочитал. Не понял. Поясните.
Пояснить как делают не правильно Вероятно ваша работа чертовски скучна
IQ>>Абсолютно не интересует. Опыт часто видно по задаваемым вопросам. Tom>>>И всё это время я учусь ибо в нашей профессии это необходимо что бы оставаться профессионалом. IQ>>Вот никогда не понимал людей, которые врут наполовину Tom>Можно по подробнее где я вру
То был намек Намеки не поясняют, их или понимают, или нет.
IQ>>Ну прочитайте уже пост! Я нигде не утверждаю что DI это зло. Наоборот, специально раз пять написал обратное. Tom>У вас DI какой то очень странный. Какой то избирательный.
так об том и пост! Не у меня, а у наивных архитекторов.
Tom>Вы так и не пояснили критерии как определить что надо DI а что не надо и главное почему не надо и какие проблемы это несёт.
Пост о том, как в DI строят на основе DAL хелперов. Я высказал предположение, что так делать не надо и ряд соображений. Если описанный пример не несет для вас проблем — пост явно не для вас. Написали бы:
"я и пару сотен разработчиков" сделали так в "несколько десятков проектов с которыми я знаком" и все отлично, зря автор париться.
Re[11]: О "наивном" DI и об архитектурном бессилии
Здравствуйте, ·, Вы писали:
·>Здравствуйте, Tom, Вы писали:
Tom>>·>SL. В подавляющем числе случаев он не нужен. Проблема — он делает зависимости неявными. Tom>>? Что такое SL? ·>Service Locator.
Так не надо его использовать. Контейнер то тут причём
Обычно контейнер встраивается бесшовно и вы навсегда забываете о его существовании и явно никогда не вызываете.
Конечно есть некоторые исключения — вершина стека вызовов. Аля новый поток но тут ничего не сделать. Кто то должен инициировать резолв дерева зависимостей но таки да использовать локатор не есть хорошо по очевидному ряду причин описанному в толпе статей.
Tom>>Абсолютно согласен, зло злейшее. В 99% только Constructor Injection. Правда есть пару случаев когда из за "чужёго кривого дизайна" приходится использовать property injection но это исключение. ·>Но вот добрый контейнер легко и непринуждённо позволяет это пихать куда угодно в любых количествах.
То что контейнер позволяет это делать не мешает вам не использовать эти плохие практики. Если вы их используете то контейнер тут не причём, это ваше собственное плохое решение. Однако как я говорил есть редкие случаи когда таки property injection необходим.
Tom>>Да конечно надо как то регистрации отличать друг от друга и ничего проще строк тут нету. Что бы эти строки перестали быть магическими — вынеси их в константу и используй эту константу как при регистарции так и при резолве. ·>А зачем тебе их по строкам отличать? Зачем их вообще отличать? Есть две ситуации. ·>Первая cитуация, у тебя действительно два инстанса и ты разные инстансы используешь в разных частях программы с разными целями. Ну например, DbConnection для основной БД и для отдельной БД для аудита, например. В этом случае тебе строки не нужны. В случае ручного связывания у тебя вместо строк это будет именем поля или локальной переменной. ·>Вторая ситуация, у тебя действительно несколько инстансов и их нужно как-то определять в рантайме в зависимости от каких-то данных. Ну например, найти инстанс какого-нибудь класса по фрагменту URL. В этом случае следует использовать не "ничего проще строк нету", а соответсвующий бизнес-требованиям тип — UrlFragment, enum, етс. Пихать везде строки — плохой стиль.
Мне казалось я понятно обьяснил зачем нужны строки. 1-е для того что бы сказать контейнеру что он не должен переопределять зависимость а должен зарегистрировать вторую для того жде интерфейса. 2-й для того что бы как то можно было зарезолвить зависимость по имени. Таких случаев тьма, случаи когда есть N обьектов реализующих один и тот же интерфейс, как пример ICommand. И никаких проблем строки не создают, обьявите их константами и используйте.
Tom>>·>Сканирование сборок. В подавляющем числе случаев он не нужен. Доставляет столько удовольствия исследовать что куда залетело и почему. Притом это можно исследовать только на запущенной системе в данном (часто prod) окружении. Tom>>Ничего не понимаю что куда залетело. В общем случае фича которая называется auto wire работает прекрасно. Регистрируешь только то что отличается от принятых в контейнере конвенций. ·>Я о http://www.lightinject.net/#assembly-scanning , а ты о чём?
И я о том же, обычно это называется auto wiring
Tom>>·>Циклические зависимости. С DI+CI сделать цикл невозможно. Заставляет аккуратнее подходить к архитектуре приложения, а не всякие lazy/PI, которые тебе циклы создадут на ура. Tom>>Эммм а где антипаттерн? И причём тут контейнеры с DI. Если у тебя циклические зависимости то это проблема не контейнера а проблема твоего дизайна. Но даже в этом случае контейнер может подставить тебе плечо, ты можешь резолвить Lazy<T> и фактически резолв будет сделан в момент использования. ·>Циклические зависимости делать не надо. Никогда. А если это действительно неизбежно — это должно быть сложно и сразу явно видно. Ты можешь случайно добавить незаметив, а контейнер тебе всё сам свяжет и не пикнет, втихую добавив +100 к техническому долгу. А потом эту вязанку развязывать.
Да действительно контейнер в случае циклической зависимости упадёт только во время резолва. У меня такая проблема встречалась один раз и выявлена была в тестах. Ничего серьёзного, решилась за пару часов.
Tom>>На стадии проектирования интерфейса и своей реализации интерфейса ты НЕ знаешь будут ли другие реализации которым может потребоваться очистка ресурсов. Это основная идея. В случае исполдьзования контейнера, обычно, на запрос создаётся так называемый child container который разрушается при окончании обработки запроса и который при разрушении вызовет Dispose у обьектов которые были в нём зарезолвлены. Причём он вызовет Dispose естественно вне зависимости от того унаследован интерфейс от IDsiposable или нет. В случае когда у тебя контейнера нет тебе надо либо самому писать такой функционал но это не возможно так как без контейнера нет единственного класса который контролирует время жизни всех обьектов. Либо наследовать интерфейс от IDisposable в тех местах где ты предпологаешь в реализациях может понадобится очистка ресурсов, но это жутко криво ибо во первых ты по сути не должен знать и не знаешь где очистка может понадобится а во вторых сам факт наследования от IDisposable это ад адский. ·>public class RequestModule и пусть он и управляет временем жизни создаваемых им IDisposable-ы ровно так как надо, а не универсальный всемогутер, который делает какую-то неявную магию.
Не понял я кто такой RequestModule и как он может определить какой обьект надо диспоузить а какой нет.
Tom>>>>Контейнеры много чего могут но это бесполезно обьяснять человеку у которого в голове установка что они зло. Tom>>·>Но это всё не надо использовать. Контейнеры можно использовать для каких-то сложных случаев, только в довольно маленьком чётко отделённом контексте, в плагинном менеджере каком-нибудь например. Но пихать везде — антипаттерн. Tom>>Так, то что это вдруг антипатотерн — это придумал ты. Основная масса современных разработчиков с этим не согласна ·>Я знаю. Сам таким был. ·>Потом попал в компанию, где история развития была такая: "что попало как попало" -> "монстр Spring Framework" -> "модный Guice" -> "DI, plain Java code". По началу тоже возмущался отстутсвием "современного" контейнера, а потом осенило.
Я кстате заметил что ты из жабы+spring пришёл по опасениям за конфиг+xml.
Сейчас контейнеры совсем лругие. Это уже не монстры а достаточно простые, быстрые и логичные девайсы.
Советую перестать их бояться, хотя бы попробовать не нескольких проектах.
Многое становиться делать проще и удобнее чем руками.
Tom>>·>Нет, просто пишешь классы-модули, которые делают wiring тестируемых поддеревьев зависимостей. И тестируешь именно их. Иначе интеграционные тесты тестируют тестовый wiring. Tom>>О чём и речь, без контейнера тебе надо собирать деревья зависимостей руками. Зачем это делать если это умеет делать контейнер. ·>Дерево зависимостей довольно сложная, но важная вещь. Оно не только является некого рода документом, описывающим высокоуровневую архитектуру, но и сдерживающим фактором говнокодинга. Если у тебя это самое дерево руками получается делать плохо, слишком сложно, непонятно, значит ты делаешь что-то не то, остановись, подумай — сделай проще. А контейнер эту всю сложность прячет под коврик и через какое-то время кроме как автоматически это дерево не строится. Контроль над сложностью потерян, значит без бутылки человек уже не разберётся что куда откуда.
Ничего контейнер не прячем, зависимости у каждого класса явные. Если их много, то эта проблема и так явная и контейнер тут не причём.
Народная мудрось
всем все никому ничего(с).
Re[12]: О "наивном" DI и об архитектурном бессилии
Здравствуйте, IQuerist, Вы писали:
IQ>Если я ничего не путаю, вам цитируют то ли книгу по DI то ли лекции
Книга или лекции вряд ли, скорее доку какого-то контейнера, о том какой он хороший и полезный, и без него любой проект не проект.
А у тебя каша в голове. Не "по DI", а по IoC, или даже IoC-контейнерам.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай