我正在为Dagger 2
使用Dependency Injection
来实现Sampler App。
但是我不能使用我的服务(SQLiteDatabase使用应用程序),因为我的应用程序无法由我的AppComponent提供:
error: android.app.Application cannot be provided without an @Inject constructor or from an @Provides-annotated method.
public abstract ch.ti8m.gol.daggerchaos.persistence.SqlDatabase provideSqlDatabae();
^
android.app.Application is injected at
ch.ti8m.gol.daggerchaos.domain.di.DomainModule.provideSQLDatabase(app)
ch.ti8m.gol.daggerchaos.persistence.SqlDatabase is provided at
ch.ti8m.gol.daggerchaos.domain.di.DomainComponent.provideSqlDatabae()
我的AppModule
@Module
class AppModule() {
@Provides
@Singleton
fun provideContext(application: Application): Context {
return application
}
@Provides
@Singleton
fun provideApplication(app: App): Application {
return app
}
}
我的AppComponent
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): Builder
fun build(): AppComponent
}
fun inject(app: App)
}
我的DomainModule
@Module
class DomainModule {
@Provides
@Singleton
fun providePizzaService(pizzaDAO: PizzaDAO): PizzaService {
return PizzaServiceImpl(pizzaDAO)
}
//TODO get Application form App Component
@Provides
@Singleton
fun provideSQLDatabase(app: Application): SqlDatabase {
return SqlDatabase(app)
}
@Provides
@Singleton
fun providePizzaDAO(db: SqlDatabase): PizzaDAO {
return PizzaDAO(db)
}
}
我的DomainComponent
@Singleton
@Component(modules = [AppModule::class, DomainModule::class])
interface DomainComponent {
fun providePizzaService(): PizzaService
fun provideSqlDatabae(): SqlDatabase
fun providePizzaDAO(): PizzaDAO
fun inject(mainActivity: MainActivity)
fun inject(activityMainPresenterImpl: ActivityMainPresenterImpl)
}
我的申请
class App : Application() {
private lateinit var domainComponent: DomainComponent
override fun onCreate() {
super.onCreate()
domainComponent = DaggerDomainComponent.builder()
.appModule(AppModule())
.application(this)
.domainModule(DomainModule())
.build()
Timber.plant(Timber.DebugTree())
}
fun getDomainComponent(): DomainComponent {
return domainComponent
}
}
我在哪里注射
class ActivityMainPresenterImpl(private val activityMainView: ActivityMainView) : ActivityMainPresenter {
@Inject
lateinit var pizzaService: PizzaService
init {
DaggerDomainComponent.builder().build().inject(this)
}
...
我刚刚开始在Android中使用Dagger 2进行依赖注入,所以我确定自己搞砸了注入结构。
有人知道我错过或未能以正确的方式实现的东西吗(我知道有很多方法可以用Dagger实现DI)?
答案 0 :(得分:1)
就匕首错误而言,您的DomainComponent似乎缺少App
实例的绑定,而该实例是提供DomainModule中使用的Application
类所必需的。
您可以将Component.Builder
添加到DomainComponent
中,以提供此功能,就像对AppComponent *所做的操作一样
@Singleton
@Component(modules = [AppModule::class, DomainModule::class])
interface DomainComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun app(app: App): Builder
fun build(): DomainComponent
}
fun inject(mainActivity: MainActivity)
}
*请注意,您的AppComponent绑定错误,因为它绑定Application
而不是App
实例。由于未使用AppComponent
,您可能不需要吗?
构建DaggerDomainComponent
时,您需要提供App
实例。
DaggerDomainComponent.builder()
.app(this) // App reference
.build()
此外,您在应用程序中创建DomainComponent
,然后创建一个新的DomainComponent
来允许演示者进行自我注入,这看起来有点奇怪-您可能希望对它进行重组,以使相同的{{ 1}}可以用于注入,每次创建一个新组件都会失去您的一些作用域。