2016-05-04 8 views
0

Я работаю над кинжалом 2 и встретился с проблемой инъекции зависимостей. Я расскажу вам о проблеме. У меня есть ApplicationComponent, как показано ниже.Проблема с кинжалом 2 с подкомпонентом и компонентом с компонентом зависимостей

@Singleton 
@Component(modules = {AppModule.class, MySubComponent.class}) 
public interface ApplicationComponent { 
    void inject(Application app); 
    List<Integer> pattern; 
    MySubComponent subcomponent(); 
} 

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

ApplicationComponent comp = DaggerApplicationComponent.builder() 
       .appModule(new ApplicationModule()) 
       .mySubModule(new MySubModule()) 
       .build(); 

Вот как я создал экземпляр компонента приложения.

Вот субкомпонент

@Singleton 
@Subcomponent(modules = MySubModule.class) 
public interface MySubComponent { 
    void inject(AClass obj); 

    INeedThis ineedthis(); 
} 

@Module 
public class MySubComponent { 
    @Provides 
    @Singleton 
    INeedThis provideINeedThis() { 
     return new INeedThis(); 
    } 
} 

Затем я создал еще один компонент, LoginComponent с ApplicationComponent как зависимость

@Scope 
@Retention(RetentionPolicy.RUNTIME) 
public @interface PerActivity{} 

@PerActivity 
@Component(dependencies = ApplicationComponent.class, modules = LoginModule.class) 
public interface LoginComponent { 
    void inject(FirstActivity activity); 
} 

Я создал экземпляр LoginComponent, как показано ниже.

LoginComponent comp = DaggerLoginComponent.builder().loginModule(new LoginModule().applicationComponent(appComponentObject).build(); 

Проблема возникает, когда я вставляю INeedThis объект в FirstActivity. Мое предположение заключается в том, что LoginComponent имеет зависимость от ApplicationComponent, которая имеет подкомпонент MySubComponent, объект INeedThis должен быть введен. Но на самом деле это не удается, и я получаю следующую ошибку.

INeedThis cannot be provided without an @Provides- or @Produces- annotated methods. 

Я прочитал много сообщений о подкомпонентах на кинжале 2. Однако они не работали должным образом. Есть что-то, чего я не хватает?

ответ

3

Прежде всего, вы не используете подкомпоненты в коде выше, и эта проблема не связана с ними, но это еще одна проблема.

Ваш LoginComponentзависит от ApplicationComponent, как заявлено с этим:

@Component(dependencies = ApplicationComponent.class, modules = LoginModule.class) 
public interface LoginComponent {} 

Что это означает, что с помощью вашего LoginComponent вы можете вводить все, что LoginComponent знает. Это все предоставлено от LoginModule, возможные объекты, которые могут быть созданы с помощью инсталляции конструктора * и выставлены объектов из вашего ApplicationComponent.

INeedThis не может быть предоставлен без @ Provides- или @ Produces-аннотированных методов.

Это говорит о том, что для INeedThis ни один из них не является истинным.

@Component(modules = {AppModule.class, MySubComponent.class}) 

Я не знаю, как/почему вы добавляете компонент как модуль.Если это опечатка, и вы добавляете MySubModule в компоненте вы просто должны добавить следующее разоблачитьINeedThis:

@Component(modules = {AppModule.class, MySubModule.class}) 
public interface ApplicationComponent { 
    //... 
    INeedThis getINeedThis(); 
} 

Если это не опечатка, и вы на самом деле хотите использовать субкомпонент, то ваш должен зависеть от фактического подкомпонента, но он будет работать одинаково, как только вы исправите свой код, чтобы фактически использовать подкомпоненты.

Учитывая ваше определение субкомпонент выше, вы бы изменить компонент приложения не перечислить компонент в качестве модуля, и добавить метод расширить ваш ApplicationComponent:

@Singleton 
@Component(modules = {AppModule.class}) // removed from modules 
public interface ApplicationComponent { 
    void inject(Application app); 
    List<Integer> pattern; 
    MySubComponent subcomponent(); // this will create your subcomponent 

    // same as above 
    // MySubComponent subcomponent(MySubModule module); use this if you also need to setup your module 
} 

Тогда вы бы создать СВОЙ субкомпонент вроде следующего:

AppComponent appComponent = DaggerAppcomponent.create(); 
MySubComponent subComponent = appComponent.subcomponent(); // call the method on your app component 

Затем, если вы измените свое LoginComponent как следующее:

@Component(dependencies = MySubComponent.class, modules = LoginModule.class) 
public interface LoginComponent { /**/ } 

Вы можете создать его, как

DaggerLoginComponent.builder().loginModule(new LoginModule().mySubComponent(subComponent).build(); 

И то же самое, что и выше, вам придется добавить getINeedThis() к интерфейсу MySubComponent к выставить объект вспомогательного графа.

+0

Идея создания подкомпонента трудно понять. Не могли бы вы рассказать мне, как установить подкомпонент? В принципе, мне нужен ApplicationComponent с подкомпонентом. Все остальные компоненты с ApplicationComponent как зависимость должны иметь доступ к подкомпоненту. Исправьте меня, если это не норма! – Renjith

+1

@Renjith, пожалуйста, имейте в виду, что этот сайт предназначен для конкретных вопросов программирования, а не для общей информации кодирования. Как или почему вам нужно использовать дополнительный компонент, зависит от того, что вы пытаетесь выполнить, и я не могу ответить на это за вас. Я обновил ответ, если вам все еще нужна дополнительная информация, вы должны искать некоторые фактические уроки и немного попробовать себя. –

+0

Спасибо за отредактированный ответ! Я попытался включить его в свое приложение, но это не сработало. Возможно, то, что я собираюсь выполнить, может быть несколько иным. Тем не менее, я углубился в некоторые из образцов github и заставил его работать. – Renjith