Подтвердить что ты не робот

Как вводить инжектор?

Ситуация: мне нужна ленивая компоновка зависимостей в некотором FooClass, поэтому я передаю Injector классу в качестве параметра конструктора.

private final Injector m_injector;

public FooClass(@Named("FooInjector") Injector injector) {
m_injector = injector;
}

Но не позволяет привязать основные классы (инжекторы, модули и т.д.). Каково решение?

4b9b3361

Ответ 1

Вы не должны использовать Injector напрямую. Вместо этого перейдите в Provider<FooClass>. Кроме того, вы должны вводить поставщика в тех местах, где вы используете FooClass.

private final Provider<FooClass> provider;

@Inject
public ClassWhereFooIsUsed(Provider<FooClass> provider) {
    this.provider = provider;
}

.... somewhere else
FooClass f = provider.get(); // This is lazy

Ответ 2

Как сказал @gpampara, Provider<T> следует использовать для ленивой/необязательной инициализации. Кроме того, как я уже сказал в ответе на ваш другой вопрос, вы должны избегать ссылок на Injector в вашем коде почти во всех случаях.

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

Если вы введете Injector, вы должны подумать о том, ПОЧЕМУ вы хотите это сделать. Почему бы вам просто не объявлять зависимости от реальных интерфейсов/классов, от которых зависит класс? Также легко добавить новую конструкцию в конструктор, поскольку он должен получить экземпляр некоторой зависимости через Injector в другом месте вашего кода, а также делает код более понятным.

Ответ 3

Как уже ответили другие, вы можете просто использовать @Inject Injector, потому что Guice определяет сам привязку.

Обычно вам нужен только один инжектор в вашем приложении, а статическая переменная - еще более простой способ хранения и доступа к синглону, чем его впрыскивание. В нашем веб-приложении мы используем stripes-guicer и получаем Инжектор из его статического метода GuiceInjectorFactory.getInjector(), когда нам это нужно (в нашем Hibernate перехватчик, например).

Я немного озадачен советом, что "вы не должны использовать Injector напрямую". Как еще я мог бы получить инъецированный экземпляр, за исключением вызова функции injector.getInstance() или injector.injectMembers()? Выхода нет. Да, вы можете определить методы провайдера, но они никогда не будут вызываться, если где-то, что-то использует Инжектор. Да, есть модули, которые используют Инжектор для вас, как ServletModule; вам нужно создать Инжектор самостоятельно, но после этого вы можете оставить его в ServletModule.

Поэтому в некоторых случаях вы можете избежать непосредственного использования Инжектора, но это не значит, что вы "не должны" использовать его. Если вы используете Guice самостоятельно без каких-либо дополнительных модулей, тогда вы "должны" использовать инжектор по всему месту, потому что другого способа запуска инъекции не существует. (Я думаю, что разработчики, которые все время пишут код внутри фреймворков, иногда забывают, что некоторые люди фактически создают свои собственные объекты.)