我们在应用程序中使用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()
}
}
但是我确定它不会起作用。有办法吗?
不确定如何实现匕首,但是这里有一个示例,您可以为非活动类提供上下文。
假设您有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
如上所述,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如何:
为此,我们需要一个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