如何通过Hilt提供PowerSync数据库实例
我有一个Hilt模块,应该提供一个PowerSync数据库实例,随后注入到 ActivitydataSource,而 ActivityDataSource 将注入到 ActivitiesRepository。
import android.content.Context
...
import com.powersync.DatabaseDriverFactory
import com.powersync.PowerSyncDatabase
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
...
import javax.inject.Qualifier
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
object PowerSyncModule {
val dotenv = dotenv()
@Provides
@Singleton
suspend fun providePowerSyncDatabase(
@ApplicationContext context: Context,
): PowerSyncDatabase {
val driverFactory = DatabaseDriverFactory(context)
val powersyncDatabase = PowerSyncDatabase(
factory = driverFactory,
schema = AppSchema,
dbFilename = "powersync.db"
)
val supabaseClient = createSupabaseClient(
supabaseUrl = dotenv["SUPABASE_URL"],
supabaseKey = dotenv["SUPABASE_KEY"]
) {
install(Postgrest)
install(Auth)
}
powersyncDatabase.connect(SupabaseConnector(
supabaseClient,
dotenv["POWERSYNC_URL"]
))
return powersyncDatabase
}
@Provides
@Singleton
fun provideActivityDataSource(powerSyncDatabase: PowerSyncDatabase): ActivityDataSource {
return ActivityDataSource(powerSyncDatabase)
}
@Provides
@Singleton
fun provideActivitiesRepository(
dataSource: ActivityDataSource
): ActivitiesRepository {
return ActivitiesRepository(dataSource)
}
}
@Singleton
class ActivityDataSource @Inject constructor(
private val powerSyncDatabase: PowerSyncDatabase
) {
...
}
@Singleton
class ActivitiesRepository @Inject constructor(
private val dataSource: ActivityDataSource
) {
...
}
然而,我收到了以下错误:
[Dagger/MissingBinding] com.powersync.PowerSyncDatabase cannot be provided without an @Provides-annotated method.
这让我感到困惑,因为我已经给该方法提供了 @Provides 注解。为什么Hilt不能提供PowerSync数据库实例?这是否与 suspend 注解有关?
解决方案
这里的问题在于你在提供函数 providePowerSyncDatabase 上使用了 suspend 修饰符。Hilt无法调用挂起函数,因此你必须将该函数设为非挂起的。
这不会带来太大问题,因为在 providePowerSyncDatabase 中唯一需要协程的只有 powersyncDatabase.connect,且那本来就不应该出现在那里。移除它,注入应该会按预期工作。
请记住,Hilt的任务只是创建对象并在需要的地方进行注入。任何额外的初始化代码都不应成为Hilt模块的一部分。在你的具体情况下,connect 调用应在 ActivityDataSource 的某处完成。具体怎么实现,取决于你想使用哪种CoroutineScope,以及连接应在何时、以何种方式被触发。不过,这与Hilt注入完全无关。
另外,你应该移除 provideActivityDataSource 和 provideActivitiesRepository,因为它们并非必需,你已经在各自类的构造函数上用 @Inject 做了注解,这就足以让Hilt知道如何创建这些对象。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。