web-dev-qa-db-fra.com

Comment utiliser la dague dans un projet de bibliothèque Android

J'essaie actuellement d'ajouter Dagger à mes Android. Pour les projets d'applications, c'est facile et clair pour moi, comment construire l'ObjectGraph. Mais je ne sais pas trop quelle est la meilleure façon de le faire ceci dans mes Android.

Dois-je continuer à construire l'ObjectGraph dans la classe Application des applications et passer l'OG à un LibraryModule - en plus d'utiliser l'OG de la bibliothèque à l'OG Apps? Ou dois-je construire l'intégralité de l'ObjectGraph dans la bibliothèque?

Que faire si j'ai besoin d'injecter une classe dans la bibliothèque par ObjectGraph.inject(this)? Dans mes projets Apps, je peux obtenir l'OG de la classe Application. Mais comment gérer cela dans la bibliothèque? Dois-je ajouter une méthode @Provides pour l'ObjectGraph?

Un grand merci pour votre aide.

Edit: En bref: Comment puis-je appeler ObjectGraph.inject(this) dans mon projet de bibliothèque où je n'ai pas accès à l'OG car il est en cours de construction dans la classe d'application?

49
sebastian

Dans le cas où quelqu'un utilisant Dagger 2 arrive ici, c'est la façon dont j'ai fait dans mon application:

Dans le module de bibliothèque, j'ai créé le module et le composant suivants:

@Module
public class ModuleUtil {

    @Provides
    public RestTemplate provideRestTemplate() {
        return new RestTemplate();
    }

}

@Singleton
@Component(
        modules = {
                ModuleUtil.class
        })
public interface MainComponent {
    void inject(Postman postman);
}

Et puis j'ai créé le Singleton ci-dessous afin de gérer les injections:

public class DaggerWrapper {

    private static MainComponent mComponent;

    public static MainComponent getComponent() {
        if (mComponent == null) {
            initComponent();
        }
        return mComponent;
    }

    private static void initComponent () {
       mComponent = DaggerMainComponent
                .builder()
                .utilModule(new ModuleUtil())
                .build();
    }
}

Quand une classe du module de bibliothèque a besoin d'injecter ses membres, j'appelle simplement DaggerWrapper.getComponent().inject(this); et ce n'est pas ça.

Je fais de cette façon:

  1. Les classes @Module appartiennent au projet principal et fournissent des implémentations que vous injectez aux éléments de bibliothèque, il n'y a donc pas de classes @Module dans les projets de bibliothèque

  2. Les éléments de bibliothèque qui attendent une dépendance doivent avoir accès à ObjectGraph et appeler .inject () sur eux-mêmes, mais le projet principal doit donner une instance ObjectGraph à la bibliothèque avec la dépendance @Module fournie

  3. Comment obtenir ObjectGraph du projet principal dans la bibliothèque? Vous pourriez avoir une interface comme celle-ci:

    interface Injector {
        void inject(Object object);
        public ObjectGraph getObjectGraph(); 
    }

Les objets contextuels comme la classe Activity ou Application implémentent cette interface (détenteurs d'objets ObjectGraph).

Si vous avez un exemple d'activité dans le module de bibliothèque qui a besoin de quelque chose à injecter du projet principal, cela ressemblerait à ceci:

class LibraryActivity extends Activity {

    @Inject ActivationModule instance;

    void onCreate(... ) {
        Injector injector = (Injector)getApplicationContext();
        injector.inject(this)
    }
}

ActivationModule est la classe/interface dans le projet de bibliothèque.

Le projet principal a une classe d'application qui implémente l'interface Injector et crée ObjectGraph avec la dépendance fournie pour ActivationModule dans le projet de bibliothèque.

class MyApplicationInTheMainProject extends Application implements Injector {

    ObjectGraph graph;

    @Override
    public void onCreate() {
        super.onCreate();
        graph = ObjectGraph.create(new ActivationModuleImpl(this));
    }

    @Override public void inject(Object object) {
        graph.inject(object);
    }

    @Override public ObjectGraph getObjectGraph() {
        return graph;
    }
}


@Module(injects = {
        LibraryActivity.class
}, library = true)
class ActivationModuleImpl implements ActivationModule {
    ....
}
12
LaLiLuLeLo

si vous donnez cette bibliothèque à des gens qui ne savent rien de votre scénario, vous devez donc l'écrire de manière à ce que votre Dagger fonctionne parfaitement sans l'aide de l'utilisateur. (plus il est facile de travailler avec les meilleures pratiques)

je viens d'écrire une bibliothèque pour vous montrer comment le faire. j'ai écrit la bibliothèque d'une manière que vous pouvez même l'exécuter de manière autonome et voir le résultat dans l'onglet messages. l'utilisateur de votre bibliothèque n'a pas besoin de rien savoir de la dague et ne fait rien, il utilise simplement la bibliothèque et la dague sera configurée:

https://github.com/amirziaratii/libraryUsingDagger.git

si cette bibliothèque est quelque chose que vous utilisez vous-même et pour votre propre projet, la meilleure pratique est de le faire comme dans ce projet de mon ami:

https://github.com/mmirhoseini/trakt.tv

toutes vos questions trouvent réponse dans ces deux projets. poser toute question et mauvaise réponse en commentaire.

5
Amir Ziarati