我可以使用 @Inject lateinit var navigator: AppNavigatorImpl 而不是 @Binds abstract fun bindNavigator(impl: AppNavigatorImpl): AppNavigator?

Hel*_*oCW 7 dependency-injection kotlin dagger-hilt

我是通过学习依赖注入的文章项目

代码A需要navigator通过依赖注入实例化一个对象,所以作者使用代码B来实现它,你可以在这里看到它。

很奇怪这个类在Code C中通过依赖注入AppNavigatorImpl实现了类AppNavigator,所以我觉得Code D会很好用。

我可以用 @Inject lateinit var navigator: AppNavigatorImpl代替@Binds abstract fun bindNavigator(impl: AppNavigatorImpl): AppNavigator吗?

代码 A

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject lateinit var navigator: AppNavigator
   

    ...
}
Run Code Online (Sandbox Code Playgroud)

代码 B

@InstallIn(ActivityComponent::class)
@Module
abstract class NavigationModule {

    @Binds
    abstract fun bindNavigator(impl: AppNavigatorImpl): AppNavigator
}
Run Code Online (Sandbox Code Playgroud)

代码 C

class AppNavigatorImpl  @Inject constructor(private val activity: FragmentActivity) : AppNavigator {

    override fun navigateTo(screen: Screens) {
        val fragment = when (screen) {
            Screens.BUTTONS -> ButtonsFragment()
            Screens.LOGS -> LogsFragment()
        }

        activity.supportFragmentManager.beginTransaction()
            .replace(R.id.main_container, fragment)
            .addToBackStack(fragment::class.java.canonicalName)
            .commit()
    }
}
Run Code Online (Sandbox Code Playgroud)

代码 D

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject lateinit var navigator: AppNavigatorImpl
   

    ...
}
Run Code Online (Sandbox Code Playgroud)

mly*_*yko 0

从技术上讲,你可以。

问题是,你是否真的想这样做。通常你想要依赖抽象,而不是具体(依赖倒置原则)。

如果您注入了AppNavigatorImpl,那么您将依赖于具体化而不是抽象化AppNavigator

此外,Codelab 中的该页面还教授如何注入接口(或抽象类),因为这些接口(或抽象类)不能使用@Inject.

在您的代码库中,您通常需要决定是否有必要进行此抽象。