2017-02-07 96 views
0

我正在嘗試使用Dagger2進行現場注入。我意識到我需要在注入方法時手動調用注入。我主要試圖爲汽車注入發動機。引擎在運行時決定,並注入。Dagger2基礎知識 - 現場注入 - 不能正常工作

的數據是這樣的

CarInterface

 import dagger.Binds; 

     public interface Car { 

      public void run(); 
     } 

汽車實現

public class Volkswagen implements Car { 

@Inject 
public Engine engine; 

public void run() { 
    // TODO Auto-generated method stub 
    System.out.println("About to Run"); 

    engine.start(); 

} 


} 

引擎接口

public interface Engine { 

public String start(); 


} 

引擎實現

public class Ferrari4Cylinder implements Engine{ 

@Override 
public String start() { 
    // TODO Auto-generated method stub 
    return "Ignition----Vroom-- Vroom-- Sweet Purring Sound"; 
} 

} 

車載模塊

public class CarModule{ 

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

} 

引擎模塊

@Module 
public class EngineModule { 

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

組件類

@Singleton 
@Component(modules = {CarModule.class, EngineModule.class}) 
public interface MyCarComponent { 

public Car provideCar(); 
void inject(Car car); 

} 

主要方法

public class Main { 

public static void main(String[] args) { 
    // TODO Auto-generated method stub 

    MyCarComponent carComponent= DaggerMyCarComponent.builder().build(); 
    Car car = carComponent.provideCar();  
    carComponent.inject(car); 
    car.run(); 
} 

} 

出於某種原因: Car.run()方法始終返回null,因爲引擎永遠不會被注入。 線程「main」中的異常java.lang.NullPointerException

任何人都可以幫助解決這裏發生的事情嗎?

更新日期09/02/2016: 我發現以下更改組件指向實際的實現工作如下所示。不知道爲什麼另一個沒有,但它幫助我在這個問題上前進。

@Singleton 
@Component(modules = {CarModule.class, EngineModule.class}) 
public interface MyCarComponent { 

public Volkswagen provideCar(); 
void inject(Volkswagen car); 

} 

希望這有助於人們試圖解決匕首的場噴射問題。

+0

此代碼,如果車廂接口是不存在的工作完全正常。我遇到了錯誤還是缺少符號? –

+0

我仍然無法理解爲什麼它不起作用。我像你一樣製作了虛擬項目,並且現場注入不適用於該項目。我在最後的評論中提出了改變,將其更改爲Volkwagen汽車,但仍然無法成功運行該項目。它仍然給出空指針異常。 –

+0

你能弄清楚這一點嗎?如果你可以給我發送代碼,我可以看看? –

回答

0

看來你忘了將EngineModule添加到MyCarComponent

爲了進行現場噴射,您應該在Car類的Engine上添加@Inject註釋。但鼓勵儘可能避免野外注射。相反,考慮這樣做:

public class Volkswagen implements Car { 

    private final Engine engine; 

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

} 

然後在CarModule

@Provides 
@Singleton 
static Car provideCar(Engine engine) { 
    return new Volkswagen(engine); 
} 

而且,這樣你就不需要組件接口上inject方法。

記得將EngineModule添加到組件,以便匕首可以提供Engine

+0

謝謝,那是一個錯字。我還發現,如果汽車接口不存在。它工作得很好。將更新我的問題。我有沒有遇到錯誤? –

+0

我不確定你的意思是「汽車接口不存在」。你可以解釋嗎? – benji

+0

如果我改變代碼看起來像這樣,它可以工作公共類大衆汽車{ @Inject public engine engine; public void run(){ // TODO自動生成方法存根 System.out.println(「關於運行」); engine.start(); }然後改變組件類看起來像這個公共Volkwagen provideCar(); void inject(大衆汽車); –

0

您需要使用@Inject註釋引擎字段。我也相信你會爲你的注射方法提供實施的課程(大衆汽車而不是汽車)。

public class Volkswagen implements Car { 

    @Inject public Engine engine; 

    public void run() { 
    System.out.println("About to Run"); 

    engine.start(); 
    } 
} 

-

@Singleton 
@Component(modules = {CarModule.class, EngineModule.class}) 
public interface MyCarComponent { 

    public Car provideCar(); 
    void inject(Volkswagen car); 

} 
+0

謝謝,我想我有EngineModule,但錯過了它的問題。在大衆汽車中加入大衆汽車,實際上使其成爲可能。但是這迫使我改變provideCar方法來返回大衆汽車而不是汽車。這很奇怪,因爲我認爲整個想法是瀏覽對象圖,並找出依賴關係。 –