Re[17]: О пользе Dependency Injection фреймворков
От: Sharov Россия  
Дата: 27.01.21 13:58
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

S>>У меня в коде операторов new практически нету,

НС>Как это связано с графом зависимостей?

У меня нету в коде операторов new, но объекты-то надо как-то создавать? При старте каким-либо образом
формирую граф зависимостей, т.е. например банальный словарь -- [тип, типы необходимые для его создания].
Все это можно делать и на ходу, но на сколько понимаю, так быстрее и проще будет понять, что что-то не то...
Чем ждать неопределенное время.
Кодом людям нужно помогать!
Отредактировано 27.01.2021 13:58 Sharov . Предыдущая версия .
Re[14]: О пользе Dependency Injection
От: Ночной Смотрящий Россия  
Дата: 27.01.21 14:37
Оценка:
Здравствуйте, Sharov, Вы писали:

НС>>Интерейс это тоже тип. Поэтому интерфейсов тоже нет.

S>Тогда это не скомпилируется.

Скомпилируется.

S>Иначе хотелось бы увидеть пример.


Я тебе привел пример, что тебе в нем не нравится?

S>>>Значит есть его интерфейс

НС>>Нету. Есть только базовый интерфейс.
S>А интерфейс, как мы знаем, тоже тип.

Но его нельзя использовать для injection.

S> И зачем нам зависить от лишнего типа?


Он не лишний.

S>>> -- это одна и та же сущность, которую по разному можно использовать.

НС>>Пошли по кругу. Еще раз — DI контейнер это частный случай service locator, он строго соответствует определению этого термина, без оговорок. Поэтому противопоставлять SL и DI контейнер ни в каком контексте нельзя, это логически некорректно.
S>Можно какой-нибудь содержательный интерент источник, где бы это утверждалось или обосновывалось?

Определение из википедии я тебе привел. Если тебе оно не нравится — это твои проблемы, оно общепринятое.

S> Мне они видятся довольно параллельными подходами. Фундаментально параллельными, что аж SL нонче считаю антипаттерном.


И что? Предлагаешь обсудить твои видения?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[18]: О пользе Dependency Injection фреймворков
От: Ночной Смотрящий Россия  
Дата: 27.01.21 14:39
Оценка:
Здравствуйте, Sharov, Вы писали:

S>>>У меня в коде операторов new практически нету,

НС>>Как это связано с графом зависимостей?
S>У меня нету в коде операторов new,

Как это связано с графом зависимостей?

S> но объекты-то надо как-то создавать? При старте каким-либо образом

S>формирую граф зависимостей

Зачем?

S>, т.е. например банальный словарь -- [тип, типы необходимые для его создания].


Банальный словарь это не граф зависимостей.

S>Все это можно делать и на ходу, но на сколько понимаю, так быстрее и проще будет понять, что что-то не то...

S>Чем ждать неопределенное время.

Вот вроде все слова понятны, а смысл фразы теряется.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[15]: О пользе Dependency Injection
От: Sharov Россия  
Дата: 27.01.21 14:49
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Скомпилируется.

S>>Иначе хотелось бы увидеть пример.
НС>Я тебе привел пример, что тебе в нем не нравится?

Вот этот?
class MyService
{
  MyService(IServiceProvider provider)
  {
        var service = provider.GetService(ResolveCustomServiceType(...));
        ...
  }
}


Хотелось бы его увидеть до конца, самое интересное скрыто за ...


НС>Он не лишний.


Для DI он не нужный.


НС>>>Пошли по кругу. Еще раз — DI контейнер это частный случай service locator, он строго соответствует определению этого термина, без оговорок. Поэтому противопоставлять SL и DI контейнер ни в каком контексте нельзя, это логически некорректно.

S>>Можно какой-нибудь содержательный интерент источник, где бы это утверждалось или обосновывалось?

НС>Определение из википедии я тебе привел. Если тебе оно не нравится — это твои проблемы, оно общепринятое.


Меня этот тезис интересует "DI контейнер это частный случай service locator", он мне кажется не совсем верным.
Если это частный случай антипаттерна, то как же тогда он может считаться лучше? Не анти-паттерном.
Кодом людям нужно помогать!
Re[16]: О пользе Dependency Injection
От: Ночной Смотрящий Россия  
Дата: 27.01.21 15:05
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Вот этот?

S>
S>class MyService
S>{
S>  MyService(IServiceProvider provider)
S>  {
S>        var service = provider.GetService(ResolveCustomServiceType(...));
S>        ...
S>  }
S>}
S>

S>Хотелось бы его увидеть до конца, самое интересное скрыто за ...

Ничего интересного там не скрыто, все что имеет отношение к делу там есть. Если что то непонятно — спрашивай.

НС>>Он не лишний.

S>Для DI он не нужный.

Он нужен для реализации требований. А что там нужно для DI — плевать.

НС>>Определение из википедии я тебе привел. Если тебе оно не нравится — это твои проблемы, оно общепринятое.

S>Меня этот тезис интересует "DI контейнер это частный случай service locator", он мне кажется не совсем верным.

Это не важно что тебе кажется. Определение из википедии говорит что он верный на 100%. Если не нравится то определение — найди другое из заслуживающего доверия источника. А фразы "мне видится" и "мне кажется" говорят только о проблемах с твоим пониманием термина, которые не вижу смысла обсуждать.

S>Если это частный случай антипаттерна, то как же тогда он может считаться лучше? Не анти-паттерном.


Потому что все эти рассказы про антипаттерн — вкусовщина отдельных личностей, а не истина в последней инстанции. В википедии на эту тему тоже сказано, если что:

Proponents of the pattern say the approach simplifies component-based applications where all dependencies are cleanly listed at the beginning of the whole application design, consequently making traditional dependency injection a more complex way of connecting objects. Critics of the pattern argue that it is an anti-pattern which obscures dependencies and makes software harder to test.

... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[17]: О пользе Dependency Injection
От: Sharov Россия  
Дата: 27.01.21 15:14
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Ничего интересного там не скрыто, все что имеет отношение к делу там есть. Если что то непонятно — спрашивай.


Да, непонятно, что там за ... скрыто. Можно увидеть полный пример?

НС>Потому что все эти рассказы про антипаттерн — вкусовщина отдельных личностей, а не истина в последней инстанции. В википедии на эту тему тоже сказано, если что:

НС>

НС>Proponents of the pattern say the approach simplifies component-based applications where all dependencies are cleanly listed at the beginning of the whole application design, consequently making traditional dependency injection a more complex way of connecting objects. Critics of the pattern argue that it is an anti-pattern which obscures dependencies and makes software harder to test.


Замечательно, но про "DI как частный случай SL" где прочитать?
Кодом людям нужно помогать!
Re[18]: О пользе Dependency Injection
От: SkyDance Земля  
Дата: 27.01.21 16:42
Оценка: +1
AA>Да не спорю я что явное лучше не явного, но иногда динамическое связывание просто необходимо.

Когда необходимо, тогда и нужно использовать. А заранее создавать объекты из собственного же репозитория путем выноса графа зависимостей куда-то в отдельное место ("composition root"), да еще и на другом языке (XML), — это без меня.
Re[18]: О пользе Dependency Injection
От: Ночной Смотрящий Россия  
Дата: 27.01.21 17:15
Оценка: :)
Здравствуйте, Sharov, Вы писали:

НС>>Ничего интересного там не скрыто, все что имеет отношение к делу там есть. Если что то непонятно — спрашивай.

S>Да, непонятно, что там за ... скрыто.

Где скрыто? Поконкретнее.

S> Можно увидеть полный пример?


Полный пример чего? Я тебя не понимаю.

S>Замечательно, но про "DI как частный случай SL" где прочитать?


Голову включить и логику в ней. DI контейнер полностью подходит под определение SL. Значит DI является SL. При этом, очевидно, не каждый SL является DI контейнером. Отсюда следует, что DI является частным случаем SL.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[19]: О пользе Dependency Injection
От: · Великобритания  
Дата: 27.01.21 17:54
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

S>>Замечательно, но про "DI как частный случай SL" где прочитать?

НС>Голову включить и логику в ней. DI контейнер полностью подходит под определение SL. Значит DI является SL. При этом, очевидно, не каждый SL является DI контейнером. Отсюда следует, что DI является частным случаем SL.
Ты понятия попутал. "DI" != "DI container". Первое — это паттерн, второе — библиотека|фреймворк, который я бы более корректно называл "IoC Container", чтобы было меньше путаницы. SL это тоже паттерн, противоположный DI:

DI directly contrasts with the service locator pattern, which allows clients to know about the system they use to find dependencies.

https://en.wikipedia.org/wiki/Dependency_injection
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[20]: О пользе Dependency Injection
От: Ночной Смотрящий Россия  
Дата: 27.01.21 18:08
Оценка:
Здравствуйте, ·, Вы писали:

·>Ты понятия попутал. "DI" != "DI container".


Ля, ну так и знал. Один раз из сотни забыл дописать контейнер, день было поправить, и тут же нашелся термин-наци. Контейнер там имелся в виду, везде — контейнер.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[21]: О пользе Dependency Injection
От: · Великобритания  
Дата: 27.01.21 19:23
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>·>Ты понятия попутал. "DI" != "DI container".

НС>Ля, ну так и знал. Один раз из сотни забыл дописать контейнер, день было поправить, и тут же нашелся термин-наци. Контейнер там имелся в виду, везде — контейнер.
Ясно, просто т.к. эти слова путают — ещё больше всё путается. Ок, вернёмся к предыдущему высказыванию, поправив слова

НС>DI контейнер полностью подходит под определение SL. Значит контейнер является SL. При этом, очевидно, не каждый SL является DI контейнером. Отсюда следует, что контейнер является частным случаем SL

По-моему тут тоже небольшая путаница из которого вырос этот ваш спор с Sharov. Контейнер сам по себе просто реестр, который предоставляет возможности SL, но и может делать DI. Т.е. формально, если взять себя в узду и никогда не использовать containter.Resolve<Type>() и аналоги, то можно использовать только DI-ную функциональность контейнера. Т.е. приложение может получиться только DI, хоть и с использованием контейнера. Вовсе не обязательно использовать контейнер как SL, или хотя бы свести к минимуму, используя только в случае интеграции с каким-то неподконтрольным 3rd party кодом.

https://softwareengineering.stackexchange.com/questions/179002/ioc-containers-and-service-locator-pattern

С другой стороны, на практике мне не доводилось такого видеть. Даже в этом топике любители контейнеров так и сыпали везде этим SL, демонстрируюя вроде как "образцово-показательный" код. По-моему, это так потому что контейнеры позволяют писать плохой код без усилий.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[22]: О пользе Dependency Injection
От: Ночной Смотрящий Россия  
Дата: 27.01.21 20:00
Оценка:
Здравствуйте, ·, Вы писали:

НС>>DI контейнер полностью подходит под определение SL. Значит контейнер является SL. При этом, очевидно, не каждый SL является DI контейнером. Отсюда следует, что контейнер является частным случаем SL

·>По-моему тут тоже небольшая путаница из которого вырос этот ваш спор с Sharov. Контейнер сам по себе просто реестр, который предоставляет возможности SL, но и может делать DI. Т.е. формально, если взять себя в узду и никогда не использовать containter.Resolve<Type>() и аналоги, то можно использовать только DI-ную функциональность контейнера.

Суть его от этого не меняется. Исторически все началось с хелперов, которые просто обеспечивали биндинг локатора и конструкторов/свойст, ну просто чтобы не писать бесконечные GetService/Resolve тоннами. Потом эти хелперы объединили с локатором в один фреймворк и обозвали модным словом injection. Вот и весь секрет Полишинеля. А потом уже бла-бла-архитекторы вывели из этого целую теорию, обозвали локатор антипаттерном а injection кошерным, и т.п.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: О пользе Dependency Injection
От: IncremenTop  
Дата: 27.01.21 20:03
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>DI это и есть проект с сервис-локаторами и синглтонами, просто в несколько более запутанном виде.


С чего бы? Я хочу настроить зависимости — я открываю один-два-три файла, а не с десяток и путешествую по ссылкам.
Re[23]: О пользе Dependency Injection
От: · Великобритания  
Дата: 27.01.21 20:37
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>·>По-моему тут тоже небольшая путаница из которого вырос этот ваш спор с Sharov. Контейнер сам по себе просто реестр, который предоставляет возможности SL, но и может делать DI. Т.е. формально, если взять себя в узду и никогда не использовать containter.Resolve<Type>() и аналоги, то можно использовать только DI-ную функциональность контейнера.

НС>Суть его от этого не меняется. Исторически все началось с хелперов, которые просто обеспечивали биндинг локатора и конструкторов/свойст, ну просто чтобы не писать бесконечные GetService/Resolve тоннами. Потом эти хелперы объединили с локатором в один фреймворк и обозвали модным словом injection. Вот и весь секрет Полишинеля. А потом уже бла-бла-архитекторы вывели из этого целую теорию, обозвали локатор антипаттерном а injection кошерным, и т.п.
Суть меняется в том смысле, что таки да, контейнер позволяет писать по старинке, но это не обязательно. Но если перестать пользоваться GetService/Resolve, выкинуть аннотации, property injection, использовать только constructor injection, то суть поменяется явно и качество кода улучшится.
Правда смысла использовать контейнер останется мало и следующий эволюционный шаг — выкинуть нафиг контейнер и получить compile-time checks.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: О пользе Dependency Injection
От: SkyDance Земля  
Дата: 27.01.21 21:02
Оценка: 5 (1) +1
IT>С чего бы? Я хочу настроить зависимости — я открываю один-два-три файла, а не с десяток и путешествую по ссылкам.

Это и есть IoC, Inversion of Control, вместо того, чтобы контролировать зависимости из source of truth (места, где зависимости возникают), приходится создавать новый "source of truth" (граф зависимостей, частенько на другом языке, скажем, XML вместо Java), и уже от него плясать.

Более удобным подходом было бы уметь генерировать граф зависимостей путем непосредственного анализа исходного кода. Однако там есть свои грабли, например, как понимать такую зависимость:

if (random(100) < 50) then add_dependency_on(AnotherComponent)

Утрировано, но смысл понятен — этакая "зависимость шредингера". Которая попросту не может быть надежно разрешена нигде, кроме конкретного экземпляра рантайма. И не надо говорить, что это редкий случай — это везде и всюду, просто чаще пишется так:

if (getenv("SOME_ENV_VARIABLE") == "true") { add_dependency(Something); }

И если такой код не содержит автотестов для всех вариантов этой самой SOME_ENV_VARIABLE, то все, попробуй угадай, что там будет происходить в реальной системе. Особенно если код addDependency сложный — например, скачивает Chromium и собирает его на локальной машине.
Re[24]: О пользе Dependency Injection
От: Ночной Смотрящий Россия  
Дата: 28.01.21 06:59
Оценка:
Здравствуйте, ·, Вы писали:

·>Суть меняется в том смысле, что таки да, контейнер позволяет писать по старинке


Суть в том, что локатор как таковой никоим образом не детерминирует способ получения сервиса. Метод ли это Resolve или DI — локатор не перестает быть локатором.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: О пользе Dependency Injection
От: Ночной Смотрящий Россия  
Дата: 28.01.21 06:59
Оценка:
Здравствуйте, IncremenTop, Вы писали:

НС>>DI это и есть проект с сервис-локаторами и синглтонами, просто в несколько более запутанном виде.

IT>С чего бы?

Я рядом раз пять ответил на этот вопрос.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[5]: О пользе Dependency Injection
От: Ночной Смотрящий Россия  
Дата: 28.01.21 06:59
Оценка:
Здравствуйте, SkyDance, Вы писали:

SD>Более удобным подходом было бы уметь генерировать граф зависимостей путем непосредственного анализа исходного кода.


Для чего более удобным?

SD> Однако там есть свои грабли, например, как понимать такую зависимость:

SD> if (random(100) < 50) then add_dependency_on(AnotherComponent)

А как такая зависимость, по твоему, понимается в случае DI? Разница тут будет только в случае вызова метода Resolve, что тут все заклеймили позором как антипаттерн..
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[17]: О пользе Dependency Injection фреймворков
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.01.21 08:24
Оценка: 5 (1) +3
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>Зачем для этого граф? DI просто заменяет явный вызов ресолва сервиса на неявный, ориентируясь на сигнатуру ктора, методов или набор свойств. Каким боком тут нужен граф зависимостей? Ты этот вопрос уже три раза проигнорировал. Если нет ответа — так и скажи.
Ну давайте напишем вот так:
public BankingService: IBankingService
{
  public BankingService(IDeliveryService deliveryService){...}
  ...
}
...
public DeliveryService: IDeliveryService
{
  public DeliveryService(IBankingService) {...}
  ...
}

Когда мы делаем "ручной DI", в какой-то момент программист вынужден написать вызовы new DeliveryService() и new BankingService(). Компилятор бъёт его по рукам, потому что получившийся DAG не сводится к дереву.
Причём неважно, где именно написан вот этот вот new — например, у нас может быть тот самый if(Configuration.Value["Delivery"] == "Active") {deliveryService = new DeliveryService(...)}. Компилятор по-прежнему проверяет definiteAssignment и non-null reference вместе с прочими ограничениями архитектуры.
Придётся почесать голову, и эту проблему как-то решить, не показывая промежуточные ошибочные стадии решения другим контрибуторам.

А когда мы полагаемся на "уолшебный контейнер", то обнаружение кольцевой зависимости откладывается до рантайма. Поэтому такой код можно прекрасно закоммитить в репозиторий; и он даже может ездить в продакшне — до тех пор, пока кто-то не попытается активировать сервис доставки при помощи конфигурации.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: О пользе Dependency Injection фреймворков
От: Ночной Смотрящий Россия  
Дата: 28.01.21 09:17
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А когда мы полагаемся на "уолшебный контейнер", то обнаружение кольцевой зависимости откладывается до рантайма. Поэтому такой код можно прекрасно закоммитить в репозиторий; и он даже может ездить в продакшне — до тех пор, пока кто-то не попытается активировать сервис доставки при помощи конфигурации.


Это все понятно, непонятно зачем контейнеру выстраивать явно граф зависимостей, тем более что он скорее всего будет неполным.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.