Модуль Dagger2 не внедряется в другой модуль или устарел

#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.