@Provides和@Binds方法在同一个类Kotlin

在匕首2.11之后,我们可以使用一个@Binds注解,并且在这种情况下将我们的模块标记为抽象,这比混凝土更有效率。

如果我的模块同时拥有@Provides和@Binds方法,我有两个选择:

  1. 最简单的方法是将你的@Provides实例方法标记为静态。

  2. 如果需要将它们保存为实例方法,那么可以将模块拆分为两个,并将所有的@Binds方法抽取到一个抽象模块中。

第二个选项在Java和Kotlin中工作正常,但第一个选项在Java中工作正常,但我不知道如何在Kotlin中实现相同。 如果将@Provides方法移动到Companion对象,则会抛出Error:(30, 1) error: @Provides methods can only be present within a @Module or @ProducerModule 。 Kotlin如何做到这一点。

第二选项:(工作)

ApplicationModule.kt

 @Module(includes = [ApplicationModule.Declarations::class]) abstract class ApplicationModule { @Module internal interface Declarations { @Binds fun bindContext(application: Application): Context } @Provides @Singleton fun provideMvpStarterService(): MvpStarterService { return MvpStarterServiceFactory.makeStarterService() } } 

第一个选项:(不工作)

ApplicationModule.kt

 @Module abstract class ApplicationModule { //expose Application as an injectable context @Binds internal abstract fun bindContext(application: Application): Context companion object { @JvmStatic @Provides @Singleton fun provideMvpStarterService(): MvpStarterService { return MvpStarterServiceFactory.makeStarterService() } } } 

生成的Java文件的第一个选项:

 @kotlin.Metadata(mv = {1, 1, 9}, bv = {1, 0, 2}, k = 1, d1 = {"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\n\u0002\u0018\u0002\n\u0002\b\u0003\b\'\u0018\u0000 \b2\u00020\u0001:\u0001\bB\u0005\u00a2\u0006\u0002\u0010\u0002J\u0015\u0010\u0003\u001a\u00020\u00042\u0006\u0010\u0005\u001a\u00020\u0006H!\u00a2\u0006\u0002\b\u0007\u00a8\u0006\t"}, d2 = {"Lio/mywebsie/di/ApplicationModule;", "", "()V", "bindContext", "Landroid/content/Context;", "application", "Landroid/app/Application;", "bindContext$app_debug", "Companion", "app_debug"}) @dagger.Module() public abstract class ApplicationModule { public static final io.mywebsie.di.ApplicationModule.Companion Companion = null; @org.jetbrains.annotations.NotNull() @dagger.Binds() public abstract android.content.Context bindContext$app_debug(@org.jetbrains.annotations.NotNull() android.app.Application application); public ApplicationModule() { super(); } @org.jetbrains.annotations.NotNull() @javax.inject.Singleton() @dagger.Provides() public static final io.mywebsie.data.remote.MvpStarterService provideMvpStarterService() { return null; } @kotlin.Metadata(mv = {1, 1, 9}, bv = {1, 0, 2}, k = 1, d1 = {"\u0000\u0012\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0018\u0002\n\u0000\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002\u00a2\u0006\u0002\u0010\u0002J\b\u0010\u0003\u001a\u00020\u0004H\u0007\u00a8\u0006\u0005"}, d2 = {"Lio/mywebsie/di/ApplicationModule$Companion;", "", "()V", "provideMvpStarterService", "Lio/mywebsie/data/remote/MvpStarterService;", "app_debug"}) public static final class Companion { @org.jetbrains.annotations.NotNull() @javax.inject.Singleton() @dagger.Provides() public final io.mywebsie.data.remote.MvpStarterService provideMvpStarterService() { return null; } private Companion() { super(); } } } 

更新:

感谢@David Medenjak你在评论中提供的链接使得一切都变得清晰我遇到了两种方法来实现第一种选择。

更新的代码:

第一选择:(工作)

ApplicationModule.kt

 @Module(includes = [ApplicationModule.AModule::class]) abstract class ApplicationModule { @Binds abstract fun bindContext(application: Application): Context @Module object AModule { @JvmStatic @Provides @Singleton fun provideMvpStarterService(): MvpStarterService { return MvpStarterServiceFactory.makeStarterService() } } } 

要么

 @Module abstract class ApplicationModule { @Binds abstract fun bindContext(application: Application): Context @Module companion object { @Provides @Singleton fun provideMvpStarterService(): MvpStarterService { return MvpStarterServiceFactory.makeStarterService() } } } 

这两个工作正常,但由于某种原因,第一个选项并不吸引我,所以我更喜欢第二个选项。