Решения задачи с Ulearn

Практика «Fractal Painter. DI-container»

При решении данной практики не бойтесь раскрывать подсказки, если возникли какие-либо трудности. В случае успешного выполнения пункта, их так же рекомендуется раскрывать, чтобы сверить ваше решение с образцом.

Продолжайте в том же проекте. Теперь, когда все базовые приготовления сделаны, приступим к внедрению DI-контейнера:

1. Исправляем MainForm

  • В классе DIContainerTask переделайте метод GetMainForm так, чтобы объект класса MainForm создавался контейнером
  • Произведите биндинг всех классов унаследованных от IUiAction (Искать в ActionsTask.cs и DIContainerTask.cs). А все зависимости для инициализации Action-объектов временно забиндите на обращение к классу Services через метод ToConstant. Все биндинги должны быть в методе ConfigureContainer.
  • Удалите из класса MainForm конструктор без параметров и так же произведите биндинг всех необходимых для инициализации аргументовНа данном этапе программа должна корректно работать. Как вы можете видеть контейнер самостоятельно создает все необходимые зависимости при создании MainForm и уже сейчас становится видно, как программа становится более простой и гибкой. Но не всегда все идет так гладко, как хотелось бы.

Подсказки

2. Исправляем KochFractalAction

  • Отрефакторите класс KochFractalAction, также как в первой практике
  • Изучите KochFractalAction и поймите, что на самом деле IImageHolder и Pallette ему не нужны. Измените его так, чтобы он принимал только KochPainter.
  • После наших действий программа работает некорректно. Подумайте из-за чего это может и попробуйте решить проблему.
  • Убедитесь, что всё ещё работает

Подсказки

3. Исправляем DragonFractalAction

  • Избавьтесь от использования класса Services в DragonFractalAction
  • Убедитесь, что все работает

4. Ребиндим IImageHolder, PictureBoxImageHolder и Palette

  • Перебиндите IImageHolder, PictureBoxImageHolder и Palette, так чтобы контейнер их создавал сам не обращаясь к классу Services
  • Убедитесь, что дракон рисуется, а палитра изменяет цвет прорисовки кривой Коха

Подсказки

5.1. Улучшаем DragonFractalAction

  • Давайте также сделаем более гибким DragonFractalAction и будем принимать все необходимые зависимости через конструктор. Дополнительное ограничение — нельзя менять публичный интерфейс DragonPainter. Особенность в том, что одна из зависимостей DragonPainter — DragonSettings оказывается известной только в процессе работы экшена. Из-за этого вы не можете просить инжектировать в конструктор уже готовый Painter. Вместо этого инжектируйте фабрику DragonPainter-ов. Интерфейс фабрики назовите IDragonPainterFactory, настройте его так чтобы, контейнер сам сгенерировал класс реализующий интерфейс фабрики.
  • Если вы все сделали правильно, то IImageHolder теперь нам больше не нужен и от него можно избавиться. Сделайте это.

Подсказки

5.2. Улучшаем DragonFractalAction (Необязательно)

  • Для создания DragonPainter-а можно также использовать Func-фабрику. Закомментируйте в конструкторе предыдущую фабрику и инжектируйте Func-фабрику в DragonFractalAction.
    (!) Интерфейс фабрики и её биндинг необходимо оставить, т.к. это проверяется в тестах.
  • Убедитесь, что все работает

Подсказки

6. Улучшаем DragonPainter

  • Переведите DragonPainter на использование цветов палитры, как это сделано в KochPainter
  • Убедитесь, что экшен настройки палитры работает как надоЕсли вы всё сделали правильно, то для добавления зависимости вам не пришлось править код работы с контейнером вообще. Магия!

Подсказки

7. Избавляемся от зависимостей класса Services

  • Избавиться от обращений к классу Services при создании AppSettings и ImageSettings. Используйте ToMethod, чтобы доставать нужные зависимости из контейнера: ToMethod(context => context.Kernel.Get<TService>() ... )
  • Убедитесь, что окно настройки размера изображения работают. Фрактал и кривая Коха должны адаптироваться под изменения изображения и не выходить за рамки в случае маленьких размеров.

Подсказки

8. Избавляемся от класса Services

  • Теперь к классу Services не происходит никаких обращений и его можно полностью удалить. Сделайте это.
  • Убедитесь, что все работаетПо прохождению данного пункта все тесты должны быть зелеными!

9. Автоматизация биндинга классов (Необязательно)

  • В больших проектах таких классов, как унаследованные от IUiActions, может быть сотни и тысячи. Подумайте, как сделать так, чтобы контейнер сам их находил и биндил.
    Не забудьте подключить библиотеку Ninject.Extensions.Conventions;
  • Убедитесь, что все работает

Стоимость решения этой задачи всего 100 рублей, купи решения у меня 🙂

Внимание! Решение было обновлено в 2021

Обновлено: 22.05.2021 — 07:54

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.