web-dev-qa-db-fra.com

Erreur d'injection de classe de type 2 générique

Je ne peux pas laisser MyClass être injecté en raison de sa nature générique. 

Dague se plaint de cette erreur: 

Erreur: (187, 10) erreur: com.test.MyClass a des paramètres de type, les membres ne peuvent pas injecter le type brut. via: com.test.MyComponent.inject (com.test.MyClass obj) [méthode d'injection de composant pour le type: com.test.MyClass]

J'ai googlé un peu mais je n'ai pas pu trouver de solution à ce scénario.

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();
    }
}
31
Andrea Baccega

J'ai rencontré le même problème et trouvé cet article .

En bref, vous avez ces options:

  1. Ne classe pas une classe wrapper générique contenant des champs injectés, fais-en un champ de ta classe et injecte-la à la place de la classe générique elle-même.
  2. Injectez la classe enfant non générique à la place de la classe de base. Tous les champs annotés avec @Inject de la classe de base seront également injectés, mais ils doivent être publics/protégés, ce qui n'est pas bon.
  3. Annoté avec le setter @Inject dans la classe de base et le champ privé. L'injection d'une classe non générique enfant entraînera le déclenchement du paramètre avec le paramètre obtenu à partir du graphe d'objet.
43
lobzik

Vous pouvez utiliser dagger2 sans "injecter".

Ajouter une méthode à votre composant:

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

UserCredentials getUserCredentials();
}

Et utilisez-le sans aucun problème:

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

Mais cette approche peut être peu pratique si vous avez beaucoup de champs à injecter.

4
alexshr

Pour beaucoup, il sera utile de savoir qu'il est permis d'injecter des champs dans une classe générique, sans injecter la classe elle-même.
Il sera injecté pour vous lorsqu’une sous-classe est injectée .
Vous pouvez donc avoir:

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

class AnotherClass extends MyClass<Type> {
    // just inject this one
}
2
Leo Droidcoder