Dagger 2 - 提供具有自己依赖性的方法

Dagger 2 - Provides methods to have dependencies of their own

我正在尝试理解和实现 Dagger 2。我已经阅读了很多不同的教程和官方 documentation。我想我大体上理解了它,但我仍然无法理解一些简单的要点(虽然我写了它,但我已经找到了一些解决方案但是..):

It's possible for @Provides methods to have dependencies of their own.

什么时候可以?

我看到有可能得到"component contains a dependency cycle"。

谁能帮助我了解可能和不可能的情况。
谢谢

经过很长一段时间的多次实验,我找到了答案。 我把这个答案作为自己的提示卡,希望它能帮助其他 daggers jedis。

所以我们有了匕首结构

  • Android应用程序
  • 基础活动
  • 导航器
  • ApplicationComponent
  • 应用模块
  • ...

ApplicationComponent.class

 @Singleton 
 @Component(modules = ApplicationModule.class)
 public interface ApplicationComponent {
     void inject(BaseActivity baseActivity);

     Navigator navigator();
     Context context();
     //...
 }

ApplicationModule.class

@Module
public class ApplicationModule {
    private final AndroidApplication application;

    public ApplicationModule(AndroidApplication application) {
        this.application = application;
    }

    @Provides
    @Singleton
    Navigator provideNavigator() {
        return new Navigator();
    }

    @Provides
    @Singleton
    Context provideApplicationContext() {
        return this.application;
    }

}

Navigator.class

@Singleton
public class Navigator implements BaseNavigator {

    public Navigator() {}

}

BaseActivity.class

public abstract class BaseActivity extends Activity {

    @Inject
    Navigator navigator;

    //code here

}

此代码将起作用,BaseActivity 将获得由 ApplicationModule 提供的 new Navigator() 导航器。

但是如果你有多个 BaseNavigator class 的实现,你可以获得一些特定的实现,例如 Navigator class 无需手动创建新实例。

*这个构造会给你"component contains a dependency cycle"

        @Provides
        @Singleton
        Navigator provideNavigator(Navigator navigator) {
            return navigator;
        }

你可以这样做:

ApplicationComponent.class

 @Singleton 
 @Component(modules = ApplicationModule.class)
 public interface ApplicationComponent {
     void inject(BaseActivity baseActivity);

     BaseNavigator navigator(); // changed to interface type
     Context context();
     //...
 }

ApplicationModule.class

@Module
public class ApplicationModule {
    private final AndroidApplication application;

    public ApplicationModule(AndroidApplication application) {
        this.application = application;
    }

    @Provides
    @Singleton
    BaseNavigator provideNavigator(Navigator navigator) {
        return navigator;
    } // this will return interface type but with implementation you needed

    @Provides
    @Singleton
    Context provideApplicationContext() {
        return this.application;
    }

}

Navigator.class

@Singleton
public class Navigator implements BaseNavigator {

    @Inject // don't forget to add this annotation to the constructor
    public Navigator() {}

}

BaseActivity.class

public abstract class BaseActivity extends Activity {

    @Inject
    BaseNavigator navigator;// changed to interface type

    //code here

}

现在您没有为 Navigator 创建新的 实例 ,Dagger 在其生成的工厂中代替您创建了它。

实际上,您可以使用限定符(@Named("something") 注释)为给定的依赖项获得多个不同类型的实现。

 @Singleton 
 @Component(modules = ApplicationModule.class)
 public interface ApplicationComponent {
     void inject(BaseActivity baseActivity);

     @Named("first")
     BaseNavigator firstNavigator();
     @Named("second")
     BaseNavigator secondNavigator();

     Context context();
     //...
 }

@Module
public class ApplicationModule {
    private final AndroidApplication application;

    public ApplicationModule(AndroidApplication application) {
        this.application = application;
    }

    @Provides
    @Singleton
    @Named("first")
    BaseNavigator provideFirstNavigator() {
        return new SomeNavigator();
    }

    @Provides
    @Singleton
    @Named("second")
    BaseNavigator provideSecondNavigator() {
        return new OtherNavigator();
    }

    @Provides
    Context provideApplicationContext() {
        return this.application;
    }

}

public abstract class BaseActivity extends Activity {

    @Inject
    @Named("second")
    BaseNavigator navigator;