是否可以在非(活动,服务,片段,应用程序)类中使用注入器

问题描述 投票:0回答:2

我们在应用程序中使用Dagger2。我正在尝试创建一个会议室数据库,并且正在编写存储库代码,但是我想为该类注入应用程序上下文和DAO。

我感觉您只能在片段,活动,服务,应用程序等中进行Dagger注入。

这里是我的东西:

class DownloadsDataRepositoryImpl : IDownloadsDataRepository, HasAndroidInjector {

      @Inject
      lateinit var androidInjector : DispatchingAndroidInjector<Any>

      @Inject
      lateinit var downloadsDao: DownloadsDao

      override fun androidInjector(): AndroidInjector<Any> = androidInjector
      init { 
         androidInjector()
      }

}

但是我确定它不会起作用。有办法吗?

android dagger-2
2个回答
0
投票

不确定如何实现匕首,但是这里有一个示例,您可以为非活动类提供上下文。

假设您有AppModule类,因此可以在其中添加ProvideContext()方法:

@Module
class AppModule(app: App) {

    private var application: Application = app

    @Provides
    fun provideContext(): Context {
        return application
    }
}

这里是用Kotlin编写的非活动类:

class Utils @inject构造函数(私有val上下文:Context){..}

就这样,只需重建j


0
投票

如上所述,dagger-android只是一个工具,可以帮助注入您无法控制创建的特定框架类。

正确的方法是使用简单的construction injection

为了更直接地说明如何在@Component上公开它,我需要更多代码,尤其是关于您的活动/片段所具有的代码,但这是一个粗略的示例(如果有的话,我没有测试过)是小错误,您可以按照编译器错误消息进行修复):

首先,您将有一些对象公开您的DAO。可能是房间?

@Entity(tableName = "download_table")
data class DownloadEntity(
    @PrimaryKey
    val key: String
)

@Dao
interface DownloadsDao {
    @Query("SELECT * FROM download_table")
    fun load(): List<DownloadEntity>
}

@Database(
    entities = [DownloadEntity::class], version = 1
)
abstract class DownloadRoomDatabase : RoomDatabase() {
    abstract val downloadsDao: DownloadsDao
}

现在,我们将创建一个带有@Inject批注的原始存储库。匕首将为我们构建此对象。请注意,我没有使用dagger-android:

interface IDownloadsDataRepository

class DownloadsDataRepositoryImpl @Inject constructor(
    val downloadsDao: DownloadsDao
) : IDownloadsDataRepository

如何将其公开给您的活动/片段/服务需要更多有关实施的详细信息。例如,如果它位于ViewModel或带有Presenter注释的@Inject内,或者您直接在活动中进行访问,则会导致不同的实现。如果没有更多详细信息,我将假设您是直接在活动中访问存储库:

class DownloadActivity : FragmentActivity() {

    @Inject
    lateinit val repo: IDownloadsDataRepository

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        DaggerDownloadComponent.factory().create(this).inject(this)
    }
}

现在我们需要指导Dagger如何:

  1. 将具体的DownloadsDataRepositoryImpl绑定到该活动所需的IDownloadsDataRepository接口中
  2. 如何提供依赖关系来构建DownloadsDataRepositoryImpl

为此,我们需要一个module

@Module
abstract class RepositoryModule {

    //We will bind our actual implementation to the IDownloadsDataRepository
    @Binds
    abstract fun bindRepo(repo: DownloadsDataRepositoryImpl): IDownloadsDataRepository


    @Module
    companion object {

        //We need the database to get access to the DAO
        @Provides
        @JvmStatic
        fun provideDataBase(context: Context): DownloadRoomDatabase =
            Room.databaseBuilder(
                context,
                DownloadRoomDatabase::class.java,
                "download_database.db"
            ).build()

        //With the database, we can provide the DAO:
        @Provides
        @JvmStatic
        fun provideDao(db: DownloadRoomDatabase): DownloadsDao = db.downloadsDao
    }
}

这样,我们就可以完成拼图的最后一部分,创建@Component

@Component(
    modules = [
        RepositoryModule::class
    ]
)
interface DownloadComponent {

    fun inject(activity: DownloadActivity)

    @Component.Factory
    interface Factory {
        fun create(context: Context): DownloadComponent
    }
}

[注意,我没有使用任何dagger-android代码,我认为它没有用,并且会引起不必要的混乱。坚持使用基本的dagger2构造就可以了。仅了解这些构造的工作原理,即可实现99.9%的应用程序:

[@Module@Component@Subcomponent

© www.soinside.com 2019 - 2024. All rights reserved.