使用Kotlin的Dagger 2中的图形错误

时间:2019-03-18 22:30:08

标签: android kotlin dagger-2

我正在尝试将Dagger 2与Kotlin一起使用,但我丢失了一些东西。当我尝试将MVP演示者注入Fragment时,问题就来了。

这些是我的文件:

AppClass

class AppClass : Application(), HasActivityInjector {

    @Inject
    lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>

    override fun onCreate() {
        super.onCreate()

        DaggerAppComponent.builder()
            .application(this)
            .build()
            .inject(this)
    }

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        MultiDex.install(this)
    }

    override fun activityInjector(): AndroidInjector<Activity> = dispatchingAndroidInjector

    companion object {
        lateinit var instance: AppClass private set
    }
}

AppComponent

@Singleton
@Component(modules = [AndroidSupportInjectionModule::class,
                    AppModule::class,
                    ActivityBuilder::class])
interface AppComponent {

    fun inject(appClass: AppClass)

    @Component.Builder
    interface Builder {

        @BindsInstance
        fun application(appClass: AppClass): Builder

        fun build(): AppComponent
    }
}

AppModule

@Module
class AppModule {

    @Provides
    @Singleton
    fun provideContext(app : AppClass) = app

    @Provides
    @Singleton
    fun provideDatabaseManager() = DatabaseManager()
}

ActivityBuilder

@Module
abstract class ActivityBuilder {

    @ContributesAndroidInjector(modules = [ActivityModule::class, HomeFragmentProvider::class])
    internal abstract fun bindHomeActivity(): HomeActivity
}

HomeFragmentProvider

@Module
public abstract class HomeFragmentProvider {

    @ContributesAndroidInjector(modules = HomeFragmentModule.class)
    abstract HomeFragment provideHomeFragmentFactory();
}

HomeFragmentModule

@Module
class HomeFragmentModule {

    @Provides
    fun provideHomePresenter(databaseManager: DatabaseManager): HomeContract.Presenter {
        return HomePresenter(databaseManager)
    }
}

HomeFragment

class HomeFragment : HomeContract.View {

    @Inject lateinit var mPresenter: HomeContract.Presenter

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidSupportInjection.inject(this)
        super.onCreate(savedInstanceState)

        if (arguments != null) {
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_home, container, false)

        return view
    }

    companion object {

        private val STARTING_PAGE_INDEX = 0

        fun newInstance(): HomeFragment {
            val fragment = HomeFragment()
            val args = Bundle()
            fragment.arguments = args
            return fragment
        }
    }
}

登录

...app/build/tmp/kapt3/stubs/debug/.../di/component/FragmentComponent.java:9: error: [Dagger/MissingBinding] ....HomeContract.Presenter cannot be provided without an @Provides-annotated method.

我尝试将DatabaseManager注入到Activity中,并且工作正常,所以我认为我的问题与Fragment依赖关系有关。

感谢您的帮助。

更新 HomePresenter

class HomePresenter() :
BasePresenter<HomeContract.View>(), HomeContract.Presenter {

private lateinit var mDatabaseManager : DatabaseManager

@Inject constructor(databaseManager: DatabaseManager) : this() {
    this.mDatabaseManager = databaseManager
}
}

2 个答案:

答案 0 :(得分:0)

将HomePresenter变量定义为函数参数,如下所示:

@Module
class HomeFragmentModule {

    @Provides
    fun provideHomePresenter(homePresenter: HomePresenter): HomeContract.Presenter {
            return homePresenter
    }
}

如下修改您的HomePresenter类:

class HomePresenter @Inject constructor(val databaseManager: DatabaseManager) :
BasePresenter<HomeContract.View>(), HomeContract.Presenter {
   ....
}

此外,您可以通过将其标记为DatabaseManager来直接使用构造函数中的val实例,而无需单独定义它。

AppComponent中,如果不使用支持片段,请尝试使用AndroidInjectionModule::class

@Singleton
@Component(modules = [AndroidInjectionModule::class,
                    AppModule::class,
                    ActivityBuilder::class])
    interface AppComponent {
        ....
    }

希望这可以解决您的问题!

答案 1 :(得分:0)

我想到了这个问题。如果我将HomeFragment中的注入从@Inject lateinit var mPresenter: HomeContract.Presenter更改为@Inject lateinit var mPresenter: HomePresenter,一切正常。