Примеры C#. DataGenerator. Dependency Injection

  Рет қаралды 27,464

Программирование - это просто

Программирование - это просто

Күн бұрын

Пікірлер: 29
@vitalygaponenko4184
@vitalygaponenko4184 7 жыл бұрын
Самое лучшее объяснение из тех, что мне удалось посмотреть. Все понятно. Спасибо! Все отлично.
@Yarkendar
@Yarkendar 8 жыл бұрын
Спасибо, это лучший урок по внедрению зависимостей. Было бы очень удобно видеть урок в виде статьи :)
@AlexS-gn9tq
@AlexS-gn9tq 6 жыл бұрын
ВАУ!!!Спасибо огромное. Это настолько простое и наглядное объяснение! Я перечитал кучу разных статей но никак не мог въехать что это такое и зачем надо, а здесь всё так просто! Супер! Спасибо!
@СаняСанин-ш6у
@СаняСанин-ш6у 2 жыл бұрын
Спасибо, лучшее объяснение!
@NatuNuarat
@NatuNuarat 8 жыл бұрын
Сегодня на работе искала информацию по dependency injection и случайно набрела на Вашу статью на хабре. Узнала автора по аватарке XD Это было так приятно, как будто встретила старого знакомого! Спасибо за Ваши уроки! Они помогли мне освоить азы чтобы стать сейчас стажером-программистом =)
@_kul879
@_kul879 2 жыл бұрын
Ве-ли-ко-ле-п-но! Хочу также про интеграционны тесты!
@sergepikovsky3385
@sergepikovsky3385 8 жыл бұрын
30. Самое время подумать о классе который будет предоставлять данные. 1-ин класс - 1-а задача! ScriptGenerator - создает скрипт. Но он должен получать откуда то данные к этому скрипту. Для этого мы создали библиотеку TestDataGenerator.Data. В ней мы и разместим класс, предоставляющий данные нашему потребителю. Принято классы, которые работают с данными называть репозитариями. Но так как мы на стадии проектирования, то начинаем не с класса, а с интерфейса. Добавляем в библиотеку интерфейс IRepository.cs и делаем интерфейс открытым (public). 31. Возвращаемся к файлам, входящим в наше приложение. Они и являются опосредованным источником данных. Почему опосредованным? Из файла EnglishWord.txt мы не напрямую берем слова, а убираем номер строк, транскрипцию, толкование, а берем лишь вычлененное слово (слова). В какой то степени обработка коснется и остальных файлов. Т.е. наш класс-репозитарий длолжен обратится к этим файлам и предоставить потребителю информацию из них в удобном для потребителя формате. 32. Перечень этих данных четко виден в примере конечного скрипта. Помним, что почта = уникальный(!) логин + случайный ящик (ящик не запрашивается у файлов). Т.е. мы запрашиваем всего 4 сущности у репозитария - Имя, Отчество, Фамилию и логин. Все остальное - генерируем. Формируем методы для получения случайных данных из репозитария GetRandom...(); для всех 4-ех сущностей. Таким образом генератор скрипта будет абстрагирован от способа получения данных. 33. GetRandomUniqLogin() имеет одну тонкость: как определять границы сессии в течении которой формируются уникальные логины? Принимаем, что логины уникальны в течении генерации одного скрипта. Далее механизм учета уникальности сбрасывается и другой скрипт может однажды принять логин, который использовался, скажем, предыдущим скриптом. Для отработки этого механизма вводим метод инициализации репозитария void Init(); 34. Ну что? Пишем unit-test-ы на репозитарий? Нет!!! Unit-test покрывает не весь код. Даже вредно покрывать весь код! Юнит тестами покрывается основная часть кода - "Слой Бизнесс-Логики", т.е. библеотека .BL . Остальные слои не покрываем тестами исходя из идеологии unit-test-ирования. Unit-test-ами покрываются только независимые методы, которые ни к чему не привязаны. "Слой Призентации" привязана либо к файловой системе (наш случай), либо к UI, либо к приему пользовательских запросов, т.е. привязан к "Внешней Среде", которую мы не можем контролировать в unit-test-ах. Нижний слой - "Слой Доступа к данным" тоже зависит, но уже от "Источника[Хранилище] Данных" (папка Files). Это может быть и БД и т.д. Именно по этому интерфейс IRepository останется не покрытым unit-test-ированием. 35. Теперь подходим к реализации. Создаем открытый класс Repositary. 36. Наследоваться этот класс должен от IRepositary. Resharper на автомате реализует все поведение с реализацией throw new NotImplementedException(); Это очень хорошое исключение. Всегда стоит применять это исключение у нереализованых методов. Ни каких null - это приведет к серьезным ошибкам! Итак, все методы исполняют throw new NotImplementedException(); На данном этапе нас такая реализация устраивает. 37. Возвращаемся к интерфейсу IScriptGenerator и для него делаем все тоже самое, что и на предыдущих двух шагах для IRepositary. Т.е. создаем наследуемый от IScriptGenerator класс ScriptGenerator и просим Resharper сгенерировать все интерфейсные методы с заглушкой - throw new NotImplementedException(); 38. Псевдореализация интерфейсных методов (а других и нет) класса ScriptGenerator готова. Теперь в тестах мы можем заглушку объектов из null преобразовать в реальные объекты: public void Init() public void Init() { { _generator = null; -> _generator = new ScriptGenerator(); } } 39. Запускаем тестирование и убеждаемся в том, что все тесты упадут (что хорошо). 40. Возвращаемся в ScriptGenerator и приступаем к реализации: - public UserEntity GenerateUser() Код тривиальный, вся логика метода в этой сроке: entity.Email = string.Format("{0}@{1}", entity.Login, randomEmailDomain); 41. Пробуем запустить тесты и получаем сообщение о не реализации репозитария. Здесь есть тонкий момент, который важно понимать: - мы тестируем не класс репозитария, - мы тестируем ScriptGenerator, т.е. логику. - нам совершенно не важно как себя ведет класс репозитария. Но как мы можем абстрогироваться от класса репозитария если мы в нашем методе постоянно к нему обращаемся??? В 99% случаев методы одного класса будут зависеть от методов другого класса, но идеология unit-tseting заключается в том, что тестируется только код одного метода. Без зависимости от другого (третьего) метода. В этом случае разработчики прибегают к приему, которая называемся иньекция зависимости (Dependency Injection). В чем он заключается (практически)? Возвращаемся в метод GenerateUser(), конкретно его первую строку: IRepository repository = new Repositary(); - это очень "нехорошая" строка кода, т.к. она гвоздями прибивает наш метод к классу репозитария, в частности к его реализации {new Repository}. Если мы захотим заменить, то мы будем должны найти в классе ScriptGenerator все методы, в которых используется репозитарий и там его заменить на какую-то другую переменную. Это очень не удобно! 42. В таких то случаях и делают инъекцию зависимостей, которая к тому же явно показывает от каких именно классов зависит наш класс. Инъекция может быть проброшена в класс многими способами, но мы рассмотрим самый очевидный - Инъекцию Через Конструктор: a) Создаем закрытое поле для чтения типа IRepositary - private readonly IRepository _repository; б) Создаем конструктор нашего класса в котором инициируем созданое поле передаваемым в конструктор параметром. в) Заменяем все ссылки на репозитарий на ссылку на вновь созданное поле. г) Коментируем (убираем) строку создания старого экземпляра репозитария. 43. Что мы получили? Наш класс полностью избавился от зависимости от репозитария. Он по прежнему обращается к объекту репозитария, но теперь зависимость от объекта репозитария поступает от конструктора класса. Т.е управление этими зависимостями возлагается на иной класс. А именно на управляющий класс по отношению к ScriptGenerator (инстанцирующий ScriptGenerator). Для изменения зависимости ему хватит поменять параметр в конструкторе. А поскольку в качестве типа параметра мы указываем не конкретный класс, а интерфейс, то мы можем сюда подставить любой класс который реализует интерфейс параметра конструктора. А таких классов может быть уже достаточно много. Теперь можно переходить к тестовому классу!
@Milording
@Milording 8 жыл бұрын
Очень круто. Жду продолжения и надеюсь, будут темы с IoC и IoC-контейнерами, а то пока это все в голове слабо связывается с DI
@BoxaShu
@BoxaShu 8 жыл бұрын
Спасибо. жду продолжения.
@anatoliymedinets241
@anatoliymedinets241 6 жыл бұрын
Однозначно лайк!
@denyszorin8675
@denyszorin8675 8 жыл бұрын
Здравствуйте, у меня есть вопрос Как правильно нужно приплюсовывать стринги ?? на собеседовании мне сказали что вот так делать нежелательно - "some string" + " new string"
@Defazze
@Defazze 8 жыл бұрын
+Денис Зорин через string.format или (в C# 6) через интерполяцию строк
@denyszorin8675
@denyszorin8675 8 жыл бұрын
+Программирование - это просто , нашел ответ на свой вопрос в вашем следующем уроке. Как вариант еще это при помощи стринг билдера ) спасибо за ответ )
@qwertyq2570
@qwertyq2570 8 жыл бұрын
+Денис Зорин Странно, что в этом такого ? Надо им Рихтера дать почитать. ) "Чтобы объединить несколько строк в одну строку, используйте оператор + языка C#: String s = "Hi" + " " + "there."; // Конкатенация трех литеральных строк образует одну литеральную строку Поскольку все строки в этом коде литеральные, компилятор выполняет их конкатенацию на этапе компиляции, в результате в метаданных модуля оказывается лишь строка "Hi there.". Конкатенация нелитеральных строк с помощью оператора + происходит на этапе выполнения. Для конкатенации нескольких строк на этапе выполнения оператор + применять нежелательно, так как он создает в куче несколько строковых объектов. Вместо него рекомендуется использовать тип System.Text.StringBuilder"
@NikitaReznikow
@NikitaReznikow 8 жыл бұрын
Спасибо за уроки, давно хотел учить тесты, сильно помогли! Такой ворос: у меня Password_Required проходит, я так понимаю что это связано с тем что, проверяет на Empty а не на Null, ибо когда меняю проверку на null тест не проходит, хотя полностью повторил ваш код?
@WorldCount
@WorldCount 8 жыл бұрын
Вот и я это заметил. Причем если в Mock изменить возвращаемое значение для имени на null, то начинает проходить тест и для имени. Походу везде надо проверять именно на null.
@WorldCount
@WorldCount 8 жыл бұрын
Вообще не пойму, в коде у автора везде на Empty проверка и у него не проходит.
@svLimones
@svLimones 8 жыл бұрын
А будет ли показаны другие типы тестов? Авто-тесты, функциональные тесты?
@Defazze
@Defazze 8 жыл бұрын
+Arthur “svLimones” Ishmatov В рамках этого курса - скорее всего нет
@jestemzbiaorusi8379
@jestemzbiaorusi8379 4 жыл бұрын
Мне кажется до меня дошло... :)
@ТуралИскендерли
@ТуралИскендерли 2 жыл бұрын
Очень хороший урок👍 Сегодня провалился на Внедрении зависимостей на собеседовании. А теперь смотрю оказывается я им пользовался довольно таки часто не зная ему названия😄. Только опять таки что то не оговаривается. Или я не понимаю. Зачем нам поменять класс Repository если другой класс тоже все равно обязан реализовать тот же интерфейс и те же методы? И следовательно зачем депенденси инжекшн в таком случае?
@sergepikovsky3385
@sergepikovsky3385 8 жыл бұрын
Прошу прощения если сделал не правильно, просто конспект всегда пишу, чтобы помнил не только мозг, но и 10 пальцев, да и вспоминать легче... может пригодиться кому.
@dimabogdan1380
@dimabogdan1380 8 жыл бұрын
+Serge Pikovsky так же делаю, отлично помогает, только конспектировать правильно нужно)
@sergepikovsky3385
@sergepikovsky3385 8 жыл бұрын
+Dima Bogdan Интересно, что по вашему правильно? У меня особых правил нет. Ну, не совсем как акын, конечно, пишу, что слышу... стараюсь придать какую то структуру записям и если решил писать не выборочно, то стараюсь не пропускать смысловых блоков лекции/урока. Есть правила Димы Богдана? :-)
@sergepikovsky3385
@sergepikovsky3385 8 жыл бұрын
+Dima Bogdan А, еще... когда я здесь написал "правильно", я имел ввиду без разрешения читающего лекцию.
@sanyasa2092
@sanyasa2092 8 жыл бұрын
Неплохо бы уроки для Windows (UWP) . Мне например уже заказывают для девайсов на разбери.
@Milording
@Milording 8 жыл бұрын
+sanya sa я попробую сделать уроки, Игорь посмотрит. Если подойдут, то ожидайте! :)
@arturbo3134
@arturbo3134 Жыл бұрын
репазитАрии :D
Примеры C#. DataGenerator. Тесты и рефакторинг
22:09
Программирование - это просто
Рет қаралды 12 М.
Dependency Injection простыми словами
18:17
devschacht “Девшахта”
Рет қаралды 88 М.
Beat Ronaldo, Win $1,000,000
22:45
MrBeast
Рет қаралды 155 МЛН
Quilt Challenge, No Skills, Just Luck#Funnyfamily #Partygames #Funny
00:32
Family Games Media
Рет қаралды 55 МЛН
BAYGUYSTAN | 1 СЕРИЯ | bayGUYS
37:51
bayGUYS
Рет қаралды 1,7 МЛН
She made herself an ear of corn from his marmalade candies🌽🌽🌽
00:38
Valja & Maxim Family
Рет қаралды 17 МЛН
Dependency Injection, The Best Pattern
13:16
CodeAesthetic
Рет қаралды 898 М.
Уроки WPF. Таблицы и списки
15:45
Программирование - это просто
Рет қаралды 50 М.
C#. Covariance and Contravariance in generic interfaces.
6:35
ExtremeCode
Рет қаралды 82 М.
Примеры C#. DataGenerator. Первые тесты
20:45
Программирование - это просто
Рет қаралды 17 М.
Путь к Dependency Injection
52:48
Valery Leontyev
Рет қаралды 17 М.
Примеры C#. DataGenerator. Структура проекта
15:24
Программирование - это просто
Рет қаралды 33 М.
ЛУЧШИЕ книги для C# программиста
10:34
ExtremeCode
Рет қаралды 164 М.
Уроки WPF. Основы разметки
21:00
Программирование - это просто
Рет қаралды 101 М.
Уроки WPF. Паттерн MVVM
23:39
Программирование - это просто
Рет қаралды 87 М.
Beat Ronaldo, Win $1,000,000
22:45
MrBeast
Рет қаралды 155 МЛН