随意构造函数注入与依赖注入框架

4

好的,我决定更深入地研究如何在我的项目中实现JUnit测试。然后我偶然发现了一篇文章,讲述使用依赖注入框架如Dagger2和Koin来简化测试的重要性。

我尝试阅读“DI到底是什么”,我理解它是一种解决A类依赖对象(例如B类和C类)的方法。

我现在通常做的是:

在Activity中创建ViewModel,ViewModel需要访问数据,所以我有SomeRepository类来处理数据。然后我通过ViewModel构造函数或使用属性注入来传递SomeRepository。如果我没弄错的话,那也是某种形式的依赖注入(如果我错了,请纠正我)。

那么,如果我现在开始使用Dagger 2会有哪些好处呢?也许进行简单的代码比较会更清晰明了?提前感谢您的回答。

Activity:

val someRepository = SomeRepository()
viewModel.init(someRepository) 

在 ViewModel 中:

class SomeViewModel : ViewModel {

    private lateinit var repository: SomeRepository

    fun init(val someRepo: SomeRepository) {
        this.repository = someRepo
    }

}
2个回答

5

Dagger通过自己的依赖图促进了依赖关系的解耦。我们需要告诉Dagger如何生成类,例如它需要一个构造函数参数。一旦定义好后,它会遍历所有依赖项,并从底层开始创建它们。如果我们无法在构造函数中注入任何依赖项(例如Retrofit),我们可以使用@Provides注解手动告诉Dagger如何创建它的实例。

让我们看一个例子:

依赖 #1 - 单个模块

@Module
class NetworkModule {

 @Provides
 fun provideRetrofit() : Retrofit  

}

依赖项 #2 - 依赖于依赖项 #1

class ApiService constructor (@Inject retrofit: Retrofit){
}

依赖关系 #3 - 依赖于 依赖关系 #2

class SomeRepository constructor (@Inject apiService: ApiService){
}

依赖项 #4 - 依赖于依赖项 #3

class SomeViewModel constructor (@Inject someRepository: SomeRepository) : ViewModel {
}

Dagger会在运行时生成所有依赖项。当您运行应用程序时,每个依赖项都已准备好,可以直接注入到构造函数中。您也可以使用字段注入来注入任何这些依赖项。

class MainAcitivty : AppCompatActivity(){

 @Inject someRepository: SomeRepository

}

你目前的方法存在的问题:

val someRepository = SomeRepository()
viewModel.init(someRepository) 
  1. 你会在不同的活动中一遍又一遍地创建一个SomeRepository()实例。
  2. 如果SomeRepository()有任何依赖项,它们也将被创建多次。
  3. 你正在进行紧密耦合。测试SomeRepository()而不涉及其依赖关系将非常困难。在单元测试中,我们只关心测试单元本身,而不是其依赖项。

1

Pro1:通俗易懂地说,依赖注入对于编写可轻松编写单元测试的解耦代码非常重要。

Pro2:它还可以将对象的依赖关系与父类分离。例如,在您的用例中,Activity 并没有直接使用 SomeRepository,但仍然需要知道它。但是,如果您像这样使用构造函数注入:

class SomeViewModel constructor (@Inject someRepository: SomeRepository) : ViewModel {
}

你的活动类只需要处理SomeViewModel对象,而SomeViewModel使用的任何依赖关系都不是它所关心的。
Pro3:DI使创建和访问单例对象非常容易。 只需定义一个如下的类,你就可以在应用程序的任何地方获得MySingleton类的单个实例。
@Singleton
class MySingleton @Inject constructor() {}

或者

@Provides @Singleton mySingleton() {}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接