为什么 Dagger2 要求我提供组件不应该提供的东西

  • 本文关键字:不应该 组件 Dagger2 android dagger-2
  • 更新时间 :
  • 英文 :


我正在尝试学习Dagger2。就在我以为我明白了的时候,我似乎卡住了。我的应用程序有两个组件,应用程序组件(单例(和条带组件(1:1 活动(,为了可读性,它们继承了一个空接口。

然后它有两个模块,ApplicationModule 和 StripeModule。

@Singleton @Component(modules = ApplicationModule.class)
public interface ApplicationComponent extends AbstractComponent ...
@PerActivity @Component(modules = { StripeModule.class }) public interface StripeComponent
extends AbstractComponent ...
@Module public class ApplicationModule
@Module public class StripeModule

ApplicationModule 提供的对象之一是导航器,我相当确定它的方式相当正确:

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

这是一个非常简单的类,其中几乎没有任何东西:

@Singleton public class Navigator

然后,当我生成代码时,会从 StripeModule - StripeModule_ProvideNavigatorFactory 生成一个额外的供应工厂。然后编译器抱怨我没有提供它 - 这是真的,也是故意的。它应仅由应用程序组件提供。问题是,为什么要生产这个工厂呢?为什么 Dagger2 不明白 StripeModule 不应该提供导航器?

假设你有一个使用 StripeComponent 注入自身的 StripeActivity 类,那么你最终可能会得到这样的场景

public class StripeActivity extends AppCompatActivity {
    @Inject
    Navigator navigator;
    @Override
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        CustomApplication application = (CustomApplication)getApplicationContext();
        StripeComponent stripeComponent = createComponent(application);
        stripeComponent.inject(this);
    }
    protected StripeComponent createComponent(CustomApplication application) {
        return DaggerStripeComponent.builder()
                .applicationComponent(application.getApplicationComponent())
                .build();
    }
}
public class CustomApplication extends Application {
    ApplicationComponent applicationComponent;
    @Override
    protected void onCreate() {
        super.onCreate();
        applicationComponent = createApplicationComponent();
    }
    protected ApplicationComponent createApplicationComponent() {
        return DaggerApplicationComponent.create();
    }
    public ApplicationComponent getApplicationComponent() {
        return applicationComponent;
    }
}
@Component(modules={ApplicationModule.class})
@Singleton
public interface ApplicationComponent {
    Navigator navigator();
}
@Component(dependencies={ApplicationComponent.class}, modules={StripeModule.class})
@PerActivity
public interface StripeComponent extends ApplicationComponent {
    void inject(StripeActivity stripeActivity);
}
@Module
public class ApplicationModule {
    @Provides
    @Singleton
    Navigator navigator() {
        return new Navigator();
    }
}
@Module
public class StripeModule {
    //@Provides
    //@PerActivity
    //...
}
@Scope
@Retention(RUNTIME)
public @interface PerActivity {
}

编辑:对于基类注入,您需要手动注入超类和子类,并且需要在组件中指定超类和子类。在这种情况下,它将像这样工作。

public abstract class BaseActivity extends AppCompatActivity {
    @Inject
    Navigator navigator;
    @Override
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
        CustomApplication application = (CustomApplication)getApplicationContext();
        ApplicationComponent component = createComponentAndInjectSelf(application);
        component.inject(this);
    }
    protected abstract ApplicationComponent createComponentAndInjectSelf(CustomApplication application);
}
public class StripeActivity extends BaseActivity {
    @Override
    public void onCreate(Bundle saveInstanceState) {
        super.onCreate(saveInstanceState);
    }
    @Override
    public StripeComponent createComponentAndInjectSelf(CustomApplication application) {
        StripeComponent stripeComponent = DaggerStripeComponent.builder()
            .applicationComponent(application.getApplicationComponent())
            .build();
        stripeComponent.inject(this);
        return stripeComponent;
    }
}
@Component(modules={ApplicationModule.class})
@Singleton
public interface ApplicationComponent {
    Navigator navigator();
    void inject(BaseActivity baseActivity);
}
@Component(dependencies={ApplicationComponent.class}, modules={StripeModule.class})
@PerActivity
public interface StripeComponent extends ApplicationComponent {
    void inject(StripeActivity stripeActivity);
}

您尚未包含确切的错误或实际取决于Navigator的代码。

但是我会假设依赖于Navigator的类是从StripeModule或安装在StripeComponent中的另一个模块提供的。

StripeComponentApplicationComponent 必须以某种方式相关,以便 StripeComponent 中的绑定使用 ApplicationComponent 提供的绑定。

您可以使用组件依赖项或子组件来关联它们。

如果你使用子组件,你会StripeComponent ApplicationComponent的子组件,这意味着它可以使用安装在ApplicationComponent模块中的任何绑定,包括用于Navigator的绑定。

如果要使用组件依赖项,则需要使StripeComponent依赖于ApplicationComponent,并且要添加一个方法Navigator navigator() ApplicationComponentStripeComponent中的绑定可以依赖于它所依赖的组件上的方法返回的任何类型。

相关内容

最新更新