Dagger2 - 何时在组件中公开对象与在模块文件中提供它们 -

Dagger2 - when to exposing objects in component vs providing them in a module file -

我不清楚在 Dagger2 中何时将对象本身暴露在组件中...让我们看一下我提供依赖项的正常方式:

@Module
public class NetworkModule {

    private static final String NAME_BASE_URL = "_BASE_URL";

    @Provides
    @Named(NAME_BASE_URL)
    String provideBaseUrlString() {
        return "http://www.pomelo.baseURL.com";//Constants.BASE_URL;
    }

    @Provides
    @Singleton
    Converter.Factory provideGsonConverter() {
        return GsonConverterFactory.create();
    }


    @Provides
    @Singleton
    Retrofit provideRetrofit(Converter.Factory converter, @Named(NAME_BASE_URL) String baseUrl) {

        return new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(converter)
                .build();
    }}

然后我将有一个 AppComponent,我会在其中声明该模块与该 AppComponent 相关联,并且我还会声明任何想要由它注入的 类,如下所示:

@Singleton
@Component(modules = { NetworkModule.class})
public interface AppComponent {

    void inject(MyActivity target);
}

但我也看到了以下内容。以retrofit依赖为例:

@Singleton
@Component(modules = { NetworkModule.class})
public interface AppComponent {
    Retrofit retrofit(); //what does it mean to define an object here ?
}

将对象本身放入组件中意味着什么?我还需要网络模块中的 provides 方法吗?我这样做是在声明什么?

What am I declaring when I do this?

组件可以公开依赖关系getter这样的结构:

@Component
public interface AppComponent {
  Retrofit retrofit(); // expose Retrofit
}

它的作用只是简单地为您提供一个getter,准确地说是一个提供方法。

如果你想自己获取依赖,你可以直接调用

Retrofit retrofit = appComponent.retrofit()

Dagger 将创建/传递对象。

Do I still need a provides method in the network module?

当然可以。这不过是一个接口,声明你的组件可以为其他人提供Retrofit。 Dagger 将只实现接口,如果无法提供对象,您可能会得到众所周知的编译错误 cannot be provided without a @Provides...

所以是的,组件仍然需要访问对象,无论这是通过构造函数注入、从模块、父组件还是依赖项发生的。


那你为什么需要这个?

可能有这样一种情况,您需要访问对象,但不能或不会注入您的依赖项。你可以使用

@Component
public interface MyComponent {
  Provider<SomeThing> someThing();
}

公开提供程序以创建 SomeThing 类型的对象。如果您计划创建某种工厂,让 Dagger 为您创建和初始化组件,这可能会有用。

更常见的方法是在 Dagger 本身中,看看 component dependencies:

As an alternative [to subcomponents], components can use bindings only from another component interface by declaring a component dependency.

如果您使用 @Component(dependencies=SomeOtherComponent.class) 只有那些像上面声明的对象可以被依赖组件访问,如果您从接口中删除 provision 方法,任何依赖组件将无法再访问它。