Здравствуйте, RusDady, Вы писали:
RD>Dependency Injection RD>В каких случаях обосновано реальное/практическое использование патерна?
В тех, когда тип пользователь не должен знать о конкретном типе зависимости.
RD>И как это использование выглядит?
Самое простое — проброс ссылки на зависимость через параметр конструктора.
Здравствуйте, 0x7be, Вы писали:
0>Здравствуйте, RusDady, Вы писали:
RD>>Dependency Injection RD>>В каких случаях обосновано реальное/практическое использование патерна? 0>В тех, когда тип пользователь не должен знать о конкретном типе зависимости.
RD>>И как это использование выглядит? 0>Самое простое — проброс ссылки на зависимость через параметр конструктора.
Не, это понятно. Я имел в виду, физически. Вот, например, есть прога, и в ней ссылка через интерфейс на ресурс..
Я создаю class library, и не хочу привязываться к какому-то определенному namespace/class, который лежит в отдельном
файле... т.е. используя эту технику я могу создать какой-то свой dll реализующий требуемый интерфэйс и подложить его вместо
существующего. Я правильно понимаю?
Здравствуйте, RusDady, Вы писали:
RD>Здравствуйте, 0x7be, Вы писали:
0>>Здравствуйте, RusDady, Вы писали:
RD>>>Dependency Injection RD>>>В каких случаях обосновано реальное/практическое использование патерна? 0>>В тех, когда тип пользователь не должен знать о конкретном типе зависимости.
RD>>>И как это использование выглядит? 0>>Самое простое — проброс ссылки на зависимость через параметр конструктора.
RD>Не, это понятно. Я имел в виду, физически. Вот, например, есть прога, и в ней ссылка через интерфейс на ресурс.. RD>Я создаю class library, и не хочу привязываться к какому-то определенному namespace/class, который лежит в отдельном RD>файле... т.е. используя эту технику я могу создать какой-то свой dll реализующий требуемый интерфэйс и подложить его вместо RD>существующего. Я правильно понимаю?
Ну да, dependency injection containerы это умеют, прописываем в конфиге нужные зависимости и заменяем одну реализацию интерфейса другой.
Здравствуйте, Qulac, Вы писали:
Q>Ну да, dependency injection containerы это умеют, прописываем в конфиге нужные зависимости и заменяем одну реализацию интерфейса другой.
Значит, как наименован namespace/class не имеет значения, а только интерфэйс?
Здравствуйте, RusDady, Вы писали:
RD>Здравствуйте, Qulac, Вы писали:
Q>>Ну да, dependency injection containerы это умеют, прописываем в конфиге нужные зависимости и заменяем одну реализацию интерфейса другой.
RD>Значит, как наименован namespace/class не имеет значения, а только интерфэйс?
RD>Но namespace/class должен быть указан в кофиге?
Если класс реализует нужный интерфейс, какая разница как он называется?
Здравствуйте, RusDady, Вы писали:
RD>Dependency Injection RD>В каких случаях обосновано реальное/практическое использование патерна? RD>И как это использование выглядит?
Вот статья, которая на пальцах объясняет зачем это нужно.
Здравствуйте, RusDady, Вы писали:
RD>Не, это понятно. Я имел в виду, физически. Вот, например, есть прога, и в ней ссылка через интерфейс на ресурс.. RD>Я создаю class library, и не хочу привязываться к какому-то определенному namespace/class, который лежит в отдельном RD>файле... т.е. используя эту технику я могу создать какой-то свой dll реализующий требуемый интерфэйс и подложить его вместо RD>существующего. Я правильно понимаю?
Не совсем. Dependency injection — это лишь принцип. В самом простом случае он реализуется руками без всяких продвинутых механизмов, реализующих плагинные инфраструктуры.
Но есть и продвинутые решения, которые позволяют реализовать нечто вроде того, что ты описал. Это разного рода IoC-контейнеры.
Здравствуйте, RusDady, Вы писали:
RD>Dependency Injection RD>В каких случаях обосновано реальное/практическое использование патерна? RD>И как это использование выглядит?
В нашей реализации можно было подменить реализацию без перекомпиливая бинарей, все делалось через контейнеры. Тут привели пример окружения Dev и Prod — тоже валидно.
Но когда я в коде виду.
Container.Register<IMyClass,MyClass>();
Рука тянется к пистолету. Вас чем обычные конструкторы, то не устраивают?
Основной принйип, если необходимо менять реализации МОДУЛЕЙ без перекомпиляции, либо компиляция с разными реализациями, то DI — это прям, то что надо. В остальных случаях стоит подумать.
Здравствуйте, RusDady, Вы писали:
RD>Dependency Injection RD>В каких случаях обосновано реальное/практическое использование патерна?
Это не паттерн. Это один из способов реализации инверсии управления (то есть, от общего к частному), наряду с функциями обратного вызова и другими приёмами.
RD>И как это использование выглядит?
Модули верхних уровней не должны зависеть от модулей нижних уровней. Оба типа модулей должны зависеть от абстракций.
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
Здравствуйте, diez_p, Вы писали:
_>Но когда я в коде виду. _>
_>Container.Register<IMyClass,MyClass>();
_>
_>Рука тянется к пистолету. Вас чем обычные конструкторы, то не устраивают?
Конструктор внесёт прямую зависимость абстракции от деталей реализации. Код выше позволяет отложить установление зависимостей на момент запуска приложения и тем самым явно управлять конфигурацией приложения.
_>Основной принйип, если необходимо менять реализации МОДУЛЕЙ без перекомпиляции, либо компиляция с разными реализациями, то DI — это прям, то что надо. В остальных случаях стоит подумать.
Это механизм плагинов. Механизм плагинов отдаёт управление конфигурацией приложения третьей стороне.
А насколько замороченно будет сделать, например, такую штуку, без модификации сборок.
DI фреймворк подставляет в IDatabaseTable не просто реализацию(DatabaseTable), а враппер вокруг этой реализации. Который логгирует, например, время выполнения методов. И отправляет в лог аргументы и результаты возвращаемые методами.
В результате должен получиться очень подробный трейс всего и вся, без захламления исходников.
class DatabaseTable_AutogeneratedWrapper : IDatabaseTable
{
public DatabaseTable_AutogeneratedWrapper(DatabaseTable o)
{
_o = o;
}
IList<DataItem> LoadItems(long id)
{
//log idreturn _o.LoadItems(id);
//log result
//log execution time
}
}
Здравствуйте, UberPsychoSvin, Вы писали:
UPS>В результате должен получиться очень подробный трейс всего и вся, без захламления исходников.
Нафигнафиг. Не, конечно забивать шуруп удобнее, чем закручивать гвоздь, но надо таки хоть иногда изучать инструменты вместо того чтоб сразу за дело браться
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, UberPsychoSvin, Вы писали:
UPS>>В результате должен получиться очень подробный трейс всего и вся, без захламления исходников.
S>Нафигнафиг. Не, конечно забивать шуруп удобнее, чем закручивать гвоздь, но надо таки хоть иногда изучать инструменты вместо того чтоб сразу за дело браться
S>Профайлер/xperf вам в помощь.
Да есть и от джет брейнс что-то подобное. Кстати, и время выполнения SQL/Oracle процедур тоже можно в системных таблицах посмотреть, без всякого шаманства.
Фих знает, я с AOP не баловался. Но с трейсом аргументов публичных методов, разве не хорошая идея? )
Здравствуйте, UberPsychoSvin, Вы писали:
UPS>Фих знает, я с AOP не баловался. Но с трейсом аргументов публичных методов, разве не хорошая идея? )
Нет конечно. Когда предлагаешь новую штуку, надо всегда обдумать ответ на вопрос "а что я буду с результатом делать?" А то потом вечно неудобняк выходит. Типовой сценарий будет примерно такой:
В первую попытку гарантированно убивается производительность, причём сразу несколькими способами — от тонны аллокаций и до затыков при собственно записи.
После N итераций это заработает, уйдёт в продакшн и тут настанет следующий этап на предмет чесать затылок: а как это дело подключать динамически?
Потому что запускать трассировку заранее — не вариант, а стопить продакшн вам ради диагностики никто не даст.
Ок, ценой героических усилий вы и это дело победили... но что вы будете делать с результатами?
Ну допустим, у вас дохленький сервис с парой сотен вызовов/сек, пара строчек лога на старт/стоп метода — четверть кб, чтоб проще было считать. Сколько у вас накопится радости за всего-то час аптайма?
И с этим разобрались? Поздравляю, дальше начинается самое интересное.
Формат вывода был не формализован, т.к. никто этим не озаботился. Как будем собирать статистику и как будем отделять начало/конец вызова методов, особенно если метод может вызывать сам себя? Как понять, что у нас затык в самом методе, а не в комбинации неправильных параметров/блокировках/соседнем потоке?
Там ещё несколько граблей впереди поджидает, чтоб не портить интригу — просто изучите как ETW/EventSource работают. Иначе вы всё равно это изучите, только сложным способом
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, UberPsychoSvin, Вы писали:
UPS>>Фих знает, я с AOP не баловался. Но с трейсом аргументов публичных методов, разве не хорошая идея? )
S>Нет конечно. Когда предлагаешь новую штуку, надо всегда обдумать ответ на вопрос "а что я буду с результатом делать?" А то потом вечно неудобняк выходит. Типовой сценарий будет примерно такой:
S>В первую попытку гарантированно убивается производительность, причём сразу несколькими способами — от тонны аллокаций и до затыков при собственно записи. S>После N итераций это заработает, уйдёт в продакшн и тут настанет следующий этап на предмет чесать затылок: а как это дело подключать динамически?
S>Потому что запускать трассировку заранее — не вариант, а стопить продакшн вам ради диагностики никто не даст.
S>Ок, ценой героических усилий вы и это дело победили... но что вы будете делать с результатами?
S>Ну допустим, у вас дохленький сервис с парой сотен вызовов/сек, пара строчек лога на старт/стоп метода — четверть кб, чтоб проще было считать. Сколько у вас накопится радости за всего-то час аптайма?
S>И с этим разобрались? Поздравляю, дальше начинается самое интересное. S>Формат вывода был не формализован, т.к. никто этим не озаботился. Как будем собирать статистику и как будем отделять начало/конец вызова методов, особенно если метод может вызывать сам себя? Как понять, что у нас затык в самом методе, а не в комбинации неправильных параметров/блокировках/соседнем потоке?
S>Там ещё несколько граблей впереди поджидает, чтоб не портить интригу — просто изучите как ETW/EventSource работают. Иначе вы всё равно это изучите, только сложным способом
Ну так не надо отладочный трейс в продакшене врубать и нет проблем. )
Здравствуйте, UberPsychoSvin, Вы писали:
S>>Там ещё несколько граблей впереди поджидает, чтоб не портить интригу — просто изучите как ETW/EventSource работают. Иначе вы всё равно это изучите, только сложным способом UPS>Ну так не надо отладочный трейс в продакшене врубать и нет проблем. )
Нюанс в том, что иногда это таки надо сделать. Причём на коде полугодовой давности, не останавливая продакшн и не убивая производительность как в выключенном, так и в включённом состоянии.
Ну и самое занятное — сделать правильные выводы из результатов неполного трейса. Очень полезно в плане "думать, затем делать".
Здравствуйте, diez_p, Вы писали:
_>Здравствуйте, RusDady, Вы писали:
_>Основной принйип, если необходимо менять реализации МОДУЛЕЙ без перекомпиляции, либо компиляция с разными реализациями, то DI — это прям, то что надо. В остальных случаях стоит подумать.