Android 无法在DomainComponent(匕首2)中提供应用程序

Android 无法在DomainComponent(匕首2)中提供应用程序,android,dependency-injection,dagger-2,dagger,Android,Dependency Injection,Dagger 2,Dagger,我正在使用dagger2为依赖注入实现一个采样器应用程序 但我不能使用我的服务(SQLiteDatabase使用应用程序),因为我的应用程序不能由我的AppComponent提供: error: android.app.Application cannot be provided without an @Inject constructor or from an @Provides-annotated method. public abstract ch.ti8m.gol.daggerc

我正在使用
dagger2
依赖注入实现一个采样器应用程序

但我不能使用我的服务(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
    }
}
@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)
    }    
}
我的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)
}
我的域名模块

@Module
class AppModule() {

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

    @Provides
    @Singleton
    fun provideApplication(app: App): Application {
        return app
    }
}
@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)
    }    
}
我的域名组件

@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 ActivityMainPresenterImpl(private val activityMainView: ActivityMainView) : ActivityMainPresenter {
    @Inject
    lateinit var pizzaService: PizzaService

    init {
        DaggerDomainComponent.builder().build().inject(this)
    }
...
我的应用程序

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
    }
}
我将其注入的位置

@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 ActivityMainPresenterImpl(private val activityMainView: ActivityMainView) : ActivityMainPresenter {
    @Inject
    lateinit var pizzaService: PizzaService

    init {
        DaggerDomainComponent.builder().build().inject(this)
    }
...
我刚开始在Android中使用Dagger 2进行依赖注入,所以我肯定我弄乱了注入结构


有人知道我错过了什么或者没有以正确的方式实现什么吗(我知道有很多方法可以用Dagger实现DI)?

就dagger错误而言,您的DomainComponent似乎缺少提供域模块中使用的
应用程序类所需的
应用程序
实例的绑定

您可以向
DomainComponent
添加
Component.Builder
以提供此功能,就像您对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绑定错误,因为它绑定的是
应用程序
,而不是
应用程序
实例。由于
AppComponent
未被使用,您可能不需要它

构建
DaggerDomainComponent
时,需要提供
应用程序
实例

DaggerDomainComponent.builder()
        .app(this) // App reference
        .build()

另外,在应用程序中创建
DomainComponent
,然后创建一个新的
DomainComponent
以允许演示者注入自己,这看起来有点奇怪-您可能希望重新构造它,以便相同的
DomainComponent
可以用于注入,每次创建一个新组件都会失去一些作用域。

您也可以发布注入代码吗?@JeelVankhede当然可以