首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >刀柄注射作为父型的子类

刀柄注射作为父型的子类
EN

Stack Overflow用户
提问于 2020-10-11 09:36:20
回答 2查看 1.1K关注 0票数 0

我有三个资料库:

代码语言:javascript
复制
interface MainRepository {
        ...
    }

interface LocalRepository {
        ...
    }

interface WebRepository {
        ...
    }

每个存储库都有自己的实现:

代码语言:javascript
复制
@Singleton
class MainRepositoryImpl @Inject constructor(
    private val localRepository: LocalRepository,
    private val webRepository: WebRepository
) : MainRepository {
...
}

@Singleton
class LocalRepositoryImpl @Inject constructor(
    private val localMapper: LocalMapper
    private val popularMovieDao: PopularMovieDao
) : LocalRepository {
...
}

@Singleton
class WebRepositoryImpl @Inject constructor(
    private val webMapper: WebMapper,
    private val popularMovieApi: PopularMovieApi
) : WebRepository {
...
}

正如您所看到的,MainRepository需要将其他两个存储库都注入其中,但是,我无法真正弄清楚如何做到这一点。

当然,我可以用LocalRepositoryImplWebRepositoryImpl类型注入它,但是为了获得更广泛的方法,我想将它注入LocalRepositoryWebRepository类型。

下面是我尝试编写的模块:

代码语言:javascript
复制
@InstallIn(ApplicationComponent::class)
@Module
object Module {

    @Singleton
    @Provides
    fun provideWebRepository(): WebRepository {
        return WebRepositoryImpl(mapper = WebMapper(), popularMovieApi = PopularMovieApi.getInstance())
    }

    @Singleton
    @Provides
    fun provideLocalRepository(): LocalRepository {
        return LocalRepositoryImpl(mapper = LocalMapper(), // Here I can't really 
            // figure out how to get @Dao since it requires DB 
            // which requires context and etc 
            // which makes me think that I've got completely wrong approach to this)
    }
}

我的LocalData模块:

代码语言:javascript
复制
@InstallIn(ApplicationComponent::class)
@Module
object LocalDataSourceModule {
    @Singleton
    @Provides
    fun provideMainDatabase(@ApplicationContext context: Context): MainDatabase = MainDatabase.getInstance(context)

    @Provides
    fun providePopularMovieDao(mainDatabase: MainDatabase): PopularMovieDao = mainDatabase.popularMovieDao()
}

我的WebData模块:

代码语言:javascript
复制
@InstallIn(ApplicationComponent::class)
@Module
object RemoteDataSourceModule {

    @Singleton
    @Provides
    fun providePopularMovieApi(): PopularMovieApi = PopularMovieApi.getInstance()
}

如何在维护接口类型(LocalRepositoryImpl &``WebRepository)的同时正确注入我所拥有的实现(LocalRepositoryImpl& WebRepositoryImpl)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-11 09:58:37

使用@Binds。不要使用object Module,而是使用以下模块:

代码语言:javascript
复制
@InstallIn(ApplicationComponent::class)
@Module
interface Module {

    @Binds
    fun bindWebRepository(repository: WebRepositoryImpl): WebRepository

    @Binds
    fun bindLocalRepository(repository: LocalRepositoryImpl): LocalRepository
}

它告诉Dagger,如果您需要WebRepository依赖,那么它必须为LocalRepositoryLocalRepositoryImpl提供WebRepositoryImpl和相同的。

What is the use case for @Binds vs @Provides annotation in Dagger2

票数 3
EN

Stack Overflow用户

发布于 2020-10-11 09:53:35

你的宝库

代码语言:javascript
复制
interface MainRepository {
        ...
}

interface LocalRepository {
        ...
}

interface WebRepository {
        ...
}

实现(这里没有@Inject或@Singleton!)

代码语言:javascript
复制
class MainRepositoryImpl constructor(
    private val localRepository: LocalRepository,
    private val webRepository: WebRepository
) : MainRepository {
...
}


class LocalRepositoryImpl constructor(
    private val localMapper: LocalMapper
    private val popularMovieDao: PopularMovieDao
) : LocalRepository {
...
}


class WebRepositoryImpl constructor(
    private val webMapper: WebMapper,
    private val popularMovieApi: PopularMovieApi
) : WebRepository {
...
}

Di.Module (仓库模块)

代码语言:javascript
复制
@Module
@InstallIn(ApplicationComponent::class)
object RepositoryModule {
    
 @Singleton
 @Provides
 fun provideMainRepository(
           localRepository: LocalRepository,
           webRepository: WebRepository
 ): MainRepository = MainRepositoryImpl(localRepository, webRepository)

 @Singleton
 @Provides
 fun provideLocalRepository(
        localMapper: LocalMapper,
        popularMovieDao: PopularMovieDao
 ): LocalRepository = LocalRepositoryImpl(localMapper, popularMovieDao)

 @Singleton
 @Provides
 fun provideWebRepository(
        webMapper: WebMapper,
        popularMovieApi: PopularMovieApi
 ): WebRepository = WebRepositoryImpl(webMapper, popularMovieApi)

试试这个,告诉我它是否有效。由于您已经用@Provides提供了所有的存储库,Dagger知道如何创建它们。您是否使用Room作为您的localDatabase?如果是,那么像创建数据库那样创建数据库可能是不正确的。如果您没有使用Room,那么您应该开始使用它,因为它会使您的生活更轻松。

下面是用匕首柄创建房间数据库的正确方法:

实体模块

代码语言:javascript
复制
@Entity(tableName = "exampleTableName")
data class ExampleEntity(
    @PrimaryKey(autoGenerate = true)
    val id: Int,
    // ... whatever you need
    val header: String = "",
    val title: String = "",
    val description: String = "",
)

ExampleDatabase

代码语言:javascript
复制
@Database(entities = [ExampleEntity::class], version = 1)
abstract class ExampleDatabase : RoomDatabase() {
    abstract fun exampleDao(): ExampleDao

    companion object {
        const val DATABASE_NAME = "example_db"
    }
}

DAO

代码语言:javascript
复制
@Dao
interface DocumentDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(exampleEntity: List<ExampleEntity>)

    @Query("SELECT * FROM exampleTableName")
    suspend fun getList(): List<ExampleEntity>
}

房间Di.Module

代码语言:javascript
复制
@Module
@InstallIn(ApplicationComponent::class)
object RoomModule {

    @Singleton
    @Provides
    fun provideExampleDB(@ApplicationContext context: Context): ExampleDatabase = Room.databaseBuilder(
        context,
        ExampleDatabase::class.java,
        ExampleDatabase.DATABASE_NAME,
    ).fallbackToDestructiveMigration().build()

    @Singleton
    @Provides
    fun provideExampleDAO(exampleDatabase: ExampleDatabase): ExampleDao = exampleDatabase.exampleDao()

  }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64302553

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档