2016-07-10 15 views
3

抽象クラスのコンストラクターにインターフェイスの実装を挿入し、それを子クラスで使用します。 kotlinでダガーは基本クラスにインターフェイスを挿入します

Error:Gradle: Dagger does not support injection into private fields 
Error:Gradle: Example.A cannot be provided without an @Provides-annotated method. 
Error:Gradle: Example.B cannot be provided without an @Inject constructor or from an @Provides-annotated method. 
Error:Gradle: Execution failed for task ':app:compileDemoDebugJavaWithJavac'. 
> Compilation failed; see the compiler error output for details. 

例:

私は、コンパイル時のエラーを持っています。

object Example { 
    interface IData { 

     fun foo() { 
     } 
    } 

    class Data : IData { 

    } 

    @Module 
    class DataModel { 
     @Provides 
     fun data(): IData = Data() 
    } 

    @Singleton 
    @Component(modules = 
    arrayOf(DataModel::class) 
    ) 
    interface Injector { 
     fun inject(a: A) 
     fun inject(b: B) 
    } 

    val graph: Injector = DaggerInjector.builder(). 
      dataModel(DataModel()). 
      build() 

    abstract class A { 

     @Inject var data: IData ? = null 

     public open fun setUp() { 
      graph.inject(this) 
     } 
    } 

    open class B : A() { 

     override fun setUp() { 
      super.setUp() 
      data!!.foo() 
     } 
    } 

    fun bar() { 
     val a = B() 
     a.setUp() 
    } 
} 

バージョン:

  • com.android.tools.build:gradle:2.1.2
  • ext.kotlin_version = '1.0.3'
  • コンパイル「com.google.dagger :短剣:2.4' org.glassfish提供
  • ':javax.annotation:10.0-B28'
  • kapt 'com.google.dagger:短剣-コンパイラ:2.4'

ここに該当する。エラーメッセージからのJava

public static class A { 
    @Inject 
    @Nullable 
    private Example.IData data; 

    @Nullable 
    protected final Example.IData getData() { 
    return this.data; 
    } 

    protected final void setData(@Nullable Example.IData <set-?>) { 
    this.data = <set-?>; 
    } 

    public void setUp() { 
    Example.INSTANCE.getGraph().inject(this); 
    } 

}

答えて

7

逆コンパイル、私はこの問題は、この行であると思う:

​​

このプロパティのバッキングフィールドがprivateであり、これは何のエラーです言った。通常lateinitキーワードは、このような場合のために使用されます。

@Inject lateinit var data: IData 

lateinitは、目に見えるダガーで生成されたクラスにそれを作る、プロパティのアクセスレベル(ここではpublic)と直接バッキングフィールドを公開するいくつかの修飾子の一つです。

+0

ありがとうございました。 何が起こっているのか理解できませんでした。データは保護され、変更可能です。 – punksta

+0

@StasShakirovあなたが添付したスニペットは、 'lateinit'を適用した後に逆コンパイルされますか? 'lateinit'の前に同じコードを実行すると、' private Example.IData data; 'の代わりにこの行が表示されます。そして、daggerは '@Iject'フィールドを設定するためにsetterを使うのではなく、直接フィールドにアクセスしようとするので、元のケースでエラーを投げます。この可視性の変更は、この修正子がもともと依存性注入サポートのために作成されたため、「lateinit」(Kotlinの主な意味に加えて)の副作用です。 – AndroidEx

+0

私は少しあなたのコメントに答えるために遅かった:)うまくいけば、それは今意味があります。 – AndroidEx

関連する問題