2017-05-21 1 views
0

Je suis en train d'essayer une injection de champ avec un poignard bien que l'injection du constructeur fonctionne parfaitement bien mais je ne sais pas ce qui ne va pas avec l'injection de champ. Peut-être que je fais mal. J'ajoute les extraits de code. J'obtiens une exception de pointeur null sur engine.start() car la dépendance au moteur n'est pas alimentée. Il est similaire aux dépendances A-> B-> C où A-> B est alimenté mais pas B-> C. Cela fait longtemps que je suis incapable de résoudre.Injection de champs de dague ne fonctionnant pas avec de simples classes Java

package com.raghav.java.car; 

import javax.inject.Inject; 

public class App 
{ 
    @Inject 
    Car car; 

    App() { 
     DaggerCarComponent.create().inject(this); 
    } 

    public static void main(String[] args) 
    { 
     App app = new App(); 
     app.perform(); 
    } 

    private void perform() { 
     car.run(); 

    } 
} 

public interface Engine { 
    void start(); 
} 

class FordEngine implements Engine { 

    public void start() { 
     System.out.println("Engine started -- Vroom Vroom"); 
    } 
} 

public interface Car { 
     void run(); 
} 

class MarutiCar implements Car { 

    @Inject 
    Engine engine; 

    public void run() { 
     engine.start(); 
     System.out.println("WOW!! Maruti Running ");   
    } 

} 

@Singleton 
@Component(modules = {CarModule.class}) 
public interface CarComponent { 

    void inject(App app); 

} 

@Module 
class CarModule { 

    @Singleton 
    @Provides 
    public Car provideCar() { 
     return new MarutiCar(); 
    } 


    @Singleton 
    @Provides 
    public Engine provideEngine() { 
     return new FordEngine(); 
    } 
} 

Répondre

0

si vous voulez faire l'injection imbriquée vous devez utiliser l'injection de constructeur sinon qui ne se fera pas automatiquement parce que lorsque vous fournissez une dépendance du style Dagger (par injection injection ou un argument constructeur dans le module) dague n'a aucune idée cette. changer vos classes comme ci-dessous:

changer votre MarutiCar comme ceci:

class MarutiCar implements Car { 

Engine engine; 

@Inject 
public MarutiCar(Engine engine) 
{ 
    this.engine = engine; 
} 

public void run() { 
    engine.start(); 
    System.out.println("WOW!! Maruti Running ");   
    } 

} 

et votre classe comme FordEngine ceci:

class FordEngine implements Engine { 

@inject 
public FordEngine() 
{ 
} 

public void start() { 
    System.out.println("Engine started -- Vroom Vroom"); 
    } 
} 

puis changez CarModule comme ci-dessous:

@Module 
class CarModule { 

@Singleton 
@Provides 
public Car provideCar(MarutiCar marutiCar) { 
    return marutiCar; 
    } 

@Singleton 
@Provides 
public Engine provideEngine(FordEngine fordEngine) { 
    return fordEngine; 
    } 
} 

MISE À JOUR: DAGGER WONT INJECT FIELDS O F Une classe qui n'est pas créée par elle-même.

Vous créez l'instance MarutiCar par vous-même, comment pensez-vous que Dagger sait ce dont elle a besoin? vous pouvez commencer une nouvelle chaîne de création de poignard dans cette classe pour y parvenir, ce qui est une chose étrange à faire. Vous devez indiquer à Dagger ce dont vous avez besoin en affichant les dépendances à l'aide de l'argument constructeur ou de la méthode module afin que l'arête les instancie pour que vous sachiez de quoi il a besoin. Dagger ne fournit pas vos champs imbriqués de dépendances imbriquées parce qu'il ne les a pas créées donc il n'a aucune idée de leurs dépendances, sauf si vous commencez une autre chaîne de création de poignard comme ce que vous avez fait dans votre classe App. il y a une autre façon, si vous ne voulez pas utiliser l'injection de constructeur qui je montre que pour vous voiture et MarutiCar classe:

@Module 
class CarModule { 

@Singleton 
@Provides 
public Car provideCar(Engine engine) { 
    MarutiCar marutiCar = new MarutiCar(engine); 
    } 

@Singleton 
@Provides 
public Engine provideEngine(FordEngine fordEngine) { 
    return fordEngine; 
    } 
} 

et la classe MarutiCar serait comme ça (pas besoin de @Inject)

class MarutiCar implements Car { 

Engine engine; 

public MarutiCar(Engine engine) 
{ 
    this.engine = engine; 
} 

public void run() { 
    engine.start(); 
    System.out.println("WOW!! Maruti Running ");   
    } 

} 
+0

L'injection du constructeur fonctionne absolument bien comme indiqué ci-dessus mais pourquoi l'injection de champ ne fonctionne pas? et pouvez-vous montrer l'instance où il est écrit "pour faire une injection imbriquée, vous devez utiliser l'injection du constructeur sinon cela n'arrivera pas automatiquement". Pourquoi il n'est pas possible d'avoir une injection de champ dans les dépendances imbriquées. Et il y a une question http://stackoverflow.com/questions/28330117/dagger-nested-injections-is-it-necessary-to-call-inject qui montre l'injection de champ est possible dans dagger1 alors pourquoi cela ne peut-il pas être possible dans Dagger2 . Et merci d'avoir répondu! –

+0

http://stackoverflow.com/questions/21694326/nested-recursive-injections-with-dagger regardez ce lien. cela explique pourquoi cela arrive. –

+0

Dagger est responsable de créer vos dépendances de ne pas injecter leurs champs injectés sauf si vous créez le composant en eux aussi. Dagger fournit uniquement les dépendances qui sont obligatoires pour créer une instance (en ajoutant un @inject à la construction). il ne cherche pas et n'injecte pas pour chaque champ dans cette dépendance. –