从这里查看Android架构蓝图"todo-mvp-dagger":https://github.com/googlesamples/android-architecture。
我试图理解Dagger2的实现,但我似乎无法弄清楚他们是如何让Dagger2提供TasksRepository的。
他们@Provides
了"provideTasksLocalDataSource"和"provideTasksRemoteDataSource",但实际的TaskRepository在哪里?
在TodoApplication类中,他们有这个:
@Inject
TasksRepository tasksRepository;
它怎么能在任何地方没有@Provides的情况下注入这个?
如果我尝试在自己的应用程序中使用相同的方法,则会出现此错误:
如果没有@Provides或@Produces注释的方法,则无法提供
所以我在蓝图代码中到处寻找,但我看不出他们自己是如何做到的。有什么技巧可以让他们没有@Provides
吗?它肯定会建立起来,所以他们以某种方式绕过了它。
有人在实际的github页面上问了同样的问题,但在撰写本文时没有答案。 https://github.com/googlesamples/android-architecture/issues/561。
我在撰写本文时的最新提交是"082bd72d62472f9caadd2979046067fb928bbfef"。
在您提到的存储库中,Dagger 2 知道如何通过标记为@Inject
的构造函数注入TasksRepository
。从源头:
@Inject
TasksRepository(@Remote TasksDataSource tasksRemoteDataSource,
@Local TasksDataSource tasksLocalDataSource) {
mTasksRemoteDataSource = tasksRemoteDataSource;
mTasksLocalDataSource = tasksLocalDataSource;
}
由于构造函数是用@Inject
注释的,Dagger 2 将尝试使用该构造函数将TasksRepository
注入到像TodoApplication
这样的消费者中。
由于TasksDataSource
已经绑定在TasksRepositoryModule
因此Dagger 2有足够的信息来进行注射,而无需额外的@Provides
或@Binds
方法的负担。
同样,您可以执行以下操作:
class Foo {
private final Bar bar;
@Inject
Foo(Bar bar) {
this.bar = bar;
}
}
class Bar {
@Inject
Bar() {}
}
class Activity extends AppCompatActivity {
@Inject Foo foo;
}
dagger 2 将能够在AppCompatActivity
体内注入Foo
.为什么?
- Dagger 2知道如何构造一个
Bar
对象(通过调用空构造函数( - Dagger 2 知道在创建
Foo
实例时,它必须使用带有单个参数Bar
的@Inject
注释的构造函数。 Foo
没有其他依赖关系,换句话说,完整的对象图是可用的。