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 方法,任何依赖组件将无法再访问它。
我不清楚在 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 方法,任何依赖组件将无法再访问它。