web-dev-qa-db-ja.com

ダガー2ジェネリックタイプクラスの挿入エラー

Genericの性質のため、ここでMyClassを注入させることはできません。

ダガーはこのエラーで文句を言います:

エラー:(187、10)エラー:com.test.MyClassには型パラメーターがあり、メンバーは生の型を挿入できません。経由:com.test.MyComponent.inject(com.test.MyClass obj)[タイプ:com.test.MyClassのコンポーネントインジェクションメソッド]

私は少しグーグルで調べましたが、このケースシナリオの解決策を見つけることができませんでした。

class MyClass<Type> {
    @Inject
    UserCredentials userCredentials;

    ResultProducer<Type> mRP;

    public MyClass(ResultProducer<Type> resultProd) {
        mRP = resultProd;
        Injector.getComponent().inject(this);
    }

    public Type getResult() {
        if (userCredentials.isLoggedIn()) {
            mRP.get();
        } else {
            mRP.getAnonymousCache();
        }
    }
}

@Component(modules = CredentialsModule.class )
interface MyComponent {
    void inject(MyClass obj);
}

@Module
class CredentialsModule {
    @Provides
    public UserCredentials provideUserCredentials() {
        return new UserCredentials();
    }
}
33
Andrea Baccega

私は同じ問題に遭遇し、 この記事 を見つけました。

簡単に言うと、次のオプションがあります。

  1. インジェクトされたフィールドを含むジェネリックラッパークラスではなく、それをクラスのフィールドにして、ジェネリッククラス自体の代わりにインジェクトします。
  2. ベースクラスの代わりに子の非ジェネリッククラスを注入します。基本クラスの@Injectフィールドで注釈が付けられたものもすべて挿入されますが、それらはパブリック/保護されなければならず、良くありません。
  3. 基本クラスとプライベートフィールドに@Injectセッターで注釈を付けます。子の非ジェネリッククラスを挿入すると、オブジェクトグラフから取得したパラメーターを使用してセッターがトリガーされます。
45
lobzik

多くの人が知っておくと便利です。クラス自体を注入することなく、フィールドをジェネリッククラスに注入できることがわかります。
インジェクションされますサブクラスがインジェクトされるとき
したがって、次のことができます。

abstract class MyClass<? extends Something> {
    @Inject UserCredentials userCredentials;
    // you can use it further
}

class AnotherClass extends MyClass<Whatever> {
    // just inject this one
}
6
Leo Droidcoder

「inject」なしでdagger2を使用できます。

コンポーネントにメソッドを追加します。

@Component(modules = CredentialsModule.class )
interface MyComponent {
void inject(MyClass obj);

UserCredentials getUserCredentials();
}

そして問題なくそれを使用してください:

userCredentials=Injector.getComponent().getUserCredentials();

ただし、注入するフィールドがたくさんある場合、このアプローチは不便です。

5
alexshr