web-dev-qa-db-fra.com

Le moyen le plus simple de créer un singleton avec / Dagger 2?

Dois-je configurer des modules, des fournisseurs et des interfaces (composants)? On dirait pas mal de frais généraux juste pour pouvoir injecter un singleton.

Quelqu'un peut-il fournir un exemple simple de singleton en utilisant Dagger 2? (montrez également comment on peut définir les propriétés du singleton comme le contexte afin que vous n'ayez pas besoin de le passer à chaque fois que vous utilisez le singleton)

17
My House

Vous n'avez besoin que de modules pour des choses que vous ne pouvez pas annoter avec le constructeur @Inject (Car par exemple, le framework le crée pour vous - comme un contexte). Si vous ne pouvez pas ajouter un constructeur @Inject, vous devez également spécifier une méthode void inject(...) dans le composant également.

Cependant, si vous pouvez le créer avec un constructeur @Inject, @Inject Fonctionne également comme une annotation de champ

@Component(modules={ContextModule.class})
@Singleton
public interface SingletonComponent {
    void inject(MainActivity mainActivity);
}

@Module
public class ContextModule {
    Context context;

    public ContextModule(Context context) {
        this.context = context;
    }

    @Provides
    Context context() {
        return context;
    }
}

@Singleton
public class MyOtherSingleton {
    @Inject
    public MyOtherSingleton() {
    }
}


@Singleton
public class MySingleton {
    @Inject Context context;
    @Inject MyOtherSingleton myOtherSingleton;

    @Inject
    public MySingleton() {
    }
}

Vous pouvez également faire des paramètres de constructeur

private final Context context;
private final MyOtherSingleton myOtherSingleton;

@Inject
public MySingleton(Context context, MyOtherSingleton myOtherSingleton) {
    this.context = context;
    this.myOtherSingleton = myOtherSingleton;
}

SingletonComponent singletonComponent = DaggerSingletonComponent.builder()
           .contextModule(CustomApplication.this)
           .build();

// and elsewhere

@Inject
MySingleton mySingleton;

// ...
    singletonComponent.inject(this);

Vérifié pour travailler:

08-23 04:39:28.418 com.zhuinden.rxrealm D/DogView: My singleton has [com.zhuinden.rxrealm.application.CustomApplication@53348a58] and [com.zhuinden.rxrealm.application.injection.test.MyOtherSingleton@5336bb74]
08-23 04:39:36.422 com.zhuinden.rxrealm D/CatView: My singleton has [com.zhuinden.rxrealm.application.CustomApplication@53348a58] and [com.zhuinden.rxrealm.application.injection.test.MyOtherSingleton@5336bb74]
14
EpicPandaForce

Il s'agit d'un texte simplifié (pas complètement précis - vérifiez les liens ci-dessous) expliquant progressivement Dagger2 et l'idée derrière. J'espère que vous pourrez lire et comprendre d'autres détails sur Dagger2 après ce texte.

Ne vous concentrez pas sur le terme singleton. Dagger2 (oubliez dagger et utilisez dagger2) existe pour appliquer la portée de l'objet. Pas la portée dont nous parlons habituellement (classes, méthodes, boucles) mais la portée au niveau architectural (vous définissez ces couches).

Certaines couches typiques de Android sont Application, Activity et Fragment. Comme vous le savez, votre application Android obtient une seule instance de la classe Application. De nombreuses instances de la classe Activity et de nombreux exemples de classe Fragment.

Vous voulez garder votre application agréable et propre et vous voulez garder vos objets là où ils appartiennent (appliquer la sémantique). Ces objets doivent être créés quelque part (généralement vous devez taper les classes/méthodes/projets d'usine - le dernier était une blague) , cet utilitaire de création a besoin être appelé quelque part et vous devez passer ces objets de quelque part à l'endroit où ils appartiennent!

C'est beaucoup de choses à taper (généralement des classes avec des noms étranges) et transmettre ces objets de l'endroit où ils ont été créés à l'endroit où ils appartiennent peut être tout à fait un défi. Surtout lorsque de nombreuses classes différentes utilisent votre objet spécial.

Dagger2 à la rescousse! Fondamentalement, il y a deux termes que vous devez comprendre. Composants et modules.

Les composants sont là pour injecter. Ils injectent à vos classes les objets dont ils ont besoin pour être construits. Les composants injectent seulement, ils ne créent pas les objets. Alors, qui crée des objets?

Les modules créent des objets que les composants injectent dans des classes qui doivent être construites. Les modules regorgent de méthodes provide InsertName . Ces méthodes créent des objets que vous devez transmettre aux classes qui en ont besoin. Une méthode provide créera toujours un nouvel objet ou réutilisera (singleton) objet déjà créé si cette méthode provide est annotée avec @Scope (vous devrez taper une nouvelle annotation de portée mais c'est un détail) . Les noms des méthodes de fourniture n'ont pas vraiment d'importance. Ce qui importe, c'est le type de retour de ces méthodes (rappelez-vous juste que les informations seront utiles plus tard) .

Lorsque vous tapez votre composant, vous devez dire quels modules sont associés à ce composant et pendant l'instanciation du composant, vous devrez transmettre les instances de module associées à ce constructeur de composant. Ensemble, les composants et les modules forment une machine d'injection moyenne.

Instanciez votre composant (Dagger2 génère des classes de générateur pour vos composants) dans la couche que vous pensez que le composant doit injecter. Par exemple, vous créez une instance ApplicationComponent dans la classe Application. Les objets injectés par ApplicationComponent ne sont créés qu'une seule fois et existent tant que l'instance ApplicationComponent existe (lors de l'injection, ils seront récupérés et non recréés) . L'instance ApplicationComponent existe tant que l'instance Application existe (donc dans Android environnement qui est fondamentalement toujours/pendant la durée de vie de l'application) .

Vous pouvez répéter la même histoire avec les classes d'activité. Instanciez ActivityComponent dans votre classe Activity, ce composant existe tant que cette activité existe. Remarquez comment les objets injectés par ActivityComponent existent uniquement pendant que ActivityComponent (instance de classe d'activité) existe. C'est la beauté de Dagger2. Les objets qui appartiennent aux couches d'activité sont littéralement étendus à la couche d'activité.

Remarque: les composants peuvent dépendre les uns des autres. Votre ActivityComponent peut dépendre de votre ApplicationComponent afin que la couche Activity puisse utiliser des objets de la couche Application (mais pas l'inverse, c'est une mauvaise conception) . De cette façon, les composants forment un arbre de dépendance qui rend la récupération et l'injection d'objets très efficaces.

Après avoir lu ceci (mes félicitations, bon monsieur), je recommande de vérifier cela lien et de vérifier conférence de Jake Wharton sur Dagger2 .

9
Spidey