Комментарии 6
Поясните пожалуйста, почему плохо сохранять ссылку на Injector? Имхо, так удобнее. А если хочется получить фреймворконезависимость, так и InjectorUtil.getInjector() возвращает вполне конкретный тип.
1. Плохо сохранять ссылку на injector именно в статическом поле. В хорошем случае в том же Guice создается Injector (явно или нет — как, например, в Guice-тесте testng), из него достаются все объекты и после этого ссылка на инжектор теряется. Если нужно динамическое создание объектов, есть сущность Provider, но ее будет недостаточно, например, для такого примера:
В классе фабрике с подобным методом следует просто объявить Inject Injector injector (в поле, либо в аргумент конструктора), никакой статики, InjectorUtil — всего лишь временное явление для упрощения рефаторинга.
2. Фреймворконезависимость — это тема отдельной статьи (частично готова), а этот материал именно о рефакторинге существующего проекта с выбором конкретного фреймворка. Вообще говоря, для DI-независимости нужно знать хорошо все DI, которые вы собираетесь поддерживать, потому что они хоть и декларируют JSR-330-совместимость, делают это по-разному. Взять к примеру дефолтные scope'ы в spring и guice (соответственно, eager singleton vs prototype), дело тут вовсе не в примере с InjectorUtil.
final String className = config.getProperty("serviceImpl");
// Class.forName(name) and check required interface for type safety
final Class<? extends Service> serviceClass = Reflection.classForName(className, Service.class);
final Service service = injector.getInstance(serviceClass);
В классе фабрике с подобным методом следует просто объявить Inject Injector injector (в поле, либо в аргумент конструктора), никакой статики, InjectorUtil — всего лишь временное явление для упрощения рефаторинга.
2. Фреймворконезависимость — это тема отдельной статьи (частично готова), а этот материал именно о рефакторинге существующего проекта с выбором конкретного фреймворка. Вообще говоря, для DI-независимости нужно знать хорошо все DI, которые вы собираетесь поддерживать, потому что они хоть и декларируют JSR-330-совместимость, делают это по-разному. Взять к примеру дефолтные scope'ы в spring и guice (соответственно, eager singleton vs prototype), дело тут вовсе не в примере с InjectorUtil.
1. Со статикой то понятно, я имел ввиду инжект в поле.
Зачет печенькам! :-)
После трёх лет жизни с Dependency Injection всё ещё нахожу, что понимать код с Dependency Injection сложнее, чем без него.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Перевод legacy-проекта на Dependency Injection. Путь Ситха