47 подписчиков
Dependency Injection
Один из двух знаменитых DI. Не путать с Dependency Inversion из SOLID.
Dependency Injection (или внедрение зависимостей) — это подход к проектировке классов, в котором зависимости объекту даются внешней сущностью.
Многие по неизвестной мне причине связывают всё в куче, и что DI без Composition Root или DI Containers не существует. Хотя изначально это вообще про другое и другие проблемы решает. Тут проще привести несколько примеров кода.
Примеры нарушения DI:
public class Foo
{
private Bar _Bar = new Bar();
}
public class Foo
{
private Bar _Bar = Bar.Instance;
}
Примеры кода по DI:
public class Foo
{
private IBar _bar;
public Foo(IBar bar)
{
_bar = bar;
}
}
public class Foo : MonoBehaviour
{
[SerializeField] private AbstractBar _bar;
}
Тут может возникнуть у кого-то короткое замыкание. Как это [SerializeField] DI? А где Zenject? DI — это вообще концепция проверяемая и соблюдаемая в рамках класса. Это просто внешнее внедрение зависимости. Абстрактный класс и сериализованное поле позволяет нам сделать такое внешнее внедрение. Позволяет подсунуть туда мок объект, написать юнит тест и так далее. Просто у нас в качестве места, где мы внедряем наши зависимости используются конфиги (префабы) и это опять-так не code-first подход, а config-first.
Неудобство в Unity вводить DI через [SerializeField] в том, что юнити не умеет в SerializeField с интерфейсами и так получится только с абстрактными классами. И у этого есть логика, так как интерфейс нельзя сериализовать. Хотя к этой концепции у меня есть вопросы. Так как если есть конкретный инстанс объекта и конкретная реализация на уровне сборки или на уровне рантайма, которая испоьзуется в качестве имплементации интерфейса, то в чём проблема её сериализовать?
В целом ничто не мешает написать свой Composition Root или Dependency Injection Container, но есть удобные и готовые типа того же Zenject.
#термин
1 минута
25 января 2023