因此,我目前正在学习匕首2,到目前为止,从我已阅读的教程中,要注入依赖项,@Inject
批注将与字段内联(对于Activity /片段)或构造函数。但是,如果我不是代码部分的所有者,并且不能添加此技术才能正常工作所需的注释,或者如果我不希望代码的其他部分知道匕首的存在,我会认为这是一个问题
我目前拥有的应用程序结构是:
我的应用程序中几乎包含这种样式的类:
class ExampleViewModelImpl(useCase: ExampleUseCase): ViewModel()
(从“活动”或类似内容中初始化)。 class ExampleUseCaseImpl(repository: ExampleRepository): ExampleUseCase
在域中class ExampleRepositoryImpl(dao: ExampleDao): ExampleRepository
在数据中使用上面的结构,我需要触摸一下App Module之外的最小类数,以便利用dagger和尽可能多的自动依赖项注入功能?如何实现此目标的代码示例将很棒。
我不确定某些术语,也无法在线找到解决方案。如果有足够的资源可以解释我的要求,那也很好。
答案 0 :(得分:1)
如果我不希望代码的其他部分知道匕首的存在。
@Inject
是Dagger实现的标准(JSR 330)。添加这些注释与Dagger没有任何关系,并且可以与其他DI框架以相同的方式使用。如果是您的代码,则应在适当的地方添加这些@Inject
注释。可以将它们视为文档:创建和使用此对象必须注入哪些构造函数/字段/方法?
您的班级唯一会知道Dagger存在的地方就是您将在其他地方创建对象的地方。
走那条路,您当然可以使用没有任何@Inject
批注的Dagger,但是您会写很多 不必要的样板并丢失同时发挥Dagger最强大的功能(代码 generation )。
@Inject
批注将与字段(对于“活动/片段”)或构造函数内联。但是,如果我不是代码部分的所有者,并且无法添加所需的注释才能使此技术正常工作,那么我会认为这是一个问题
这就是@BindsInstance
与@Component.Builder
的作用(向组件添加对象),以及@Provides
带注释的方法的作用(从模块创建和初始化对象)>
如果您确实想在没有@Inject
的情况下编写代码,那么您将对所有对象完全执行 。这意味着一个很多的模块,以及更多的@Provides
带注释的方法。它将起作用,但是如果构造函数上的单个@Inject
具有相同的效果,我认为编写所有这些方法没有意义。
在我看来,关于Dagger的最好的事情就是我可以添加/删除/更改构造函数参数,而不必接触代码的任何其他部分,因为Dagger会使用新的参数生成新的代码。在您的情况下,您还必须将参数更改为@Provides
方法以及构造函数调用。
接下来让我们看看如何从字段中删除@Inject
。基本上,您不想进行字段注入,因此,您无需编写组件中的注入方法,而可以编写配置方法。
@Component
class MyComponent {
fun inject(activity: MyActivity)
}
class MyActivity {
@Inject lateinit var myDep: Dependency
fun onCreate() {
component.inject(this)
}
}
要删除@Inject
,我们需要改用供应方法。
@Component
class MyComponent {
fun provisionMyDependency() : Dependency
}
class MyActivity {
lateinit var myDep: Dependency
fun onCreate() {
myDep = component.provisionMyDependency()
}
}
它可以正常工作,但是再次,您将错过Dagger的唯一最佳功能:代码生成。上面的示例看起来不错,因为我仅添加了一个依赖项,但考虑添加/删除/更改依赖项时,这两种不同实现会发生什么,扩展性如何。如果您喜欢手动操作,那么任何重构都会变得很困难。
使用上面的结构,我需要触摸一下App Module之外的最小类数,以便利用dagger和尽可能多的自动依赖项注入功能?
您的问题(尤其是标题)与您的目标直接冲突。如果您不想使用这些注释,那么就不能使用Dagger代码生成和注入,而必须如上所述手动进行。
使用尽可能多的自动依赖项注入
要最好地利用Dagger,请在应该在依赖关系图上结束的每个类的构造函数和/或字段上添加@Inject
,然后让Dagger来做。