#java #dependency-injection #dagger-2
#java #внедрение зависимостей #кинжал-2
Вопрос:
Я пытаюсь изучить Dagger2, но модуль становится устаревшим. Я следую руководству из http://www.vogella.com/tutorials/Dagger/article.html Вот мой код следующим образом.
public class TestApp {
@Inject
BackendService backendService;
private void testServer() {
BackendComponent backendComponent = DaggerBackendComponent.builder()
.build();
backendComponent.inject(this);
backendService.call();
}
public static void main(String[] args) {
new TestApp().testServer();
}
}
Пользовательский модуль, внедрение которого не работает
@Module
public class UserModule {
@Provides
@Singleton
User providesUser() {
return new User("John", "Doe");
}
}
BackendService
public class BackendService {
@Inject
public User user;
private String serverUrl;
@Inject
public BackendService(@Named("serverUrl") String serverUrl) {
this.serverUrl = serverUrl;
}
public boolean call() {
if (user != null amp;amp; serverUrl != null amp;amp; serverUrl.length() > 0) {
System.out.println("User: " user.toString());
return true;
} else {
System.err.println("User: " user);
System.err.println("ServerUrl: " serverUrl);
return false;
}
}
}
BackendServiceModule
@Module
public class BackendServiceModule {
@Provides
@Singleton
BackendService proviedBackendServiceModule(@Named("serverUrl") String serverUrl) {
return new BackendService(serverUrl);
}
@Provides
@Named("testUrl")
String provideAnotherUrl() {
return "http://www.facebook.com";
}
@Provides
@Named("serverUrl")
String provideServerUrl() {
return "http://www.google.com";
}
}
BackendComponent
@Singleton
@Component(modules = {UserModule.class, BackendServiceModule.class})
public interface BackendComponent {
BackendService proviedBackendServiceModule();
void inject(TestApp app);
}
После запуска я получаю вывод следующим образом:
User: null
ServerUrl: http://www.google.com
Если я попытаюсь выполнить следующий код, он будет работать
public class TestApp {
@Inject
User user;
@Inject
BackendService backendService;
private void testServer() {
BackendComponent backendComponent = DaggerBackendComponent.builder()
.build();
backendComponent.inject(this);
backendService.call();
System.out.println("User: " user);
}
public static void main(String[] args) {
new TestApp().testServer();
}
}
User: null
ServerUrl: http://www.google.com
User: User [firstName=John, lastName=Doe]
Комментарии:
1. Пожалуйста, предоставьте код серверного компонента.
2. @Jacob теперь я добавил код BackendComponent, пожалуйста, проверьте.
Ответ №1:
Причина вашей проблемы заключается в том, как работает dagger. Он вводит только поля, помеченные символом @Inject, в класс, указанный вами в качестве параметра метода inject . Поэтому ничего внутри вашего серверного сервиса, помеченного @Inject, не будет введено.
public class TestApp {
@Inject <-- this is injected
User user;
@Inject <-- this is injected
BackendService backendService; <-- Nothing inside this class will be injected
Я бы рекомендовал передать ваш пользовательский объект вашему серверному сервису внутри конструктора. Просто сделайте что-то вроде этого:
@Provides
@Singleton
BackendService proviedBackendServiceModule(@Named("serverUrl") String serverUrl, User user) {
return new BackendService(serverUrl, user);
}
Другим решением было бы определить метод inject для BackendService внутри вашего компонента, но это приведет к беспорядку при передаче объекта component.