2012-09-04 157 views
2

我不確定我完全理解依賴注入背後的想法,特別是使用Guice。使用guice注入對象

我有相當大的swing應用程序,我想介紹guice來解耦這個應用程序。 假設我有噴射器主類

Guice.createInjector(new BindingModule()); 
Application app = injector.getInstance(Application.class); 
app.run(); 

和它的作品。如果我有一些字段,比如JPanel,在Application類中,用@Inject註釋,然後注入它。但是如果我在應用程序構造函數 中手動創建一些比JTree更好的例子,將不會被注入(假設所有內容都已正確配置)。

class Application { 

      @Inject JPanel mainPanel //this will be injected 

      JPanel otherPanel; 


      public Application() { 
       otherPanel = new MyNewPanel(); 

       mainPanel.add(otherPanel); 
      } 

} 

class MyNewPanel extends JPanel { 


      @Inject JTree tree; //this will not be injected 

      public MyNewPanel() { 

       add(tree); 
      } 

} 

我的問題是,我是否需要注入所有注入的控制guice的對象。 我無法打破控制,就像我用otherPanel做的那樣。

回答

0

如果你想要或必須使用新的,你可以使用供應商guice providers或 onmand和注入guice injections。 `注射器注射器= Guice.createInjector(...);

MyNewPanel myNewPanel = new MyNewPanel(); 
injector.injectMembers(myNewPanel);` 

上面的代碼可以稍微改寫爲使用標準注入。

class Application { 

     final JPanel mainPanel; 

     final JPanel otherPanel; 


     @Inject 
     public Application(@Named("main") JPanel mainPanel, @Named("other") JPanel otherPanel) { 
      this.otherPanel = otherPanel; 
      this.mainPanel = mainPanel; 
      mainPanel.add(otherPanel);    
     } 

} 

class MyNewPanel extends JPanel { 


     @Inject JTree tree; 

     public MyNewPanel() { 

      add(tree); 
     } 

} 

當你有兩個不同的面板注入你有你通過命名區別開來,即與annotatedWith

binder.bind(JPanel.class).annotatedWith(Names.named("other").to(MyNewPanel.class); 

綁定它們或者你在應用程序構造函數中使用MyNewPanel。但是這種聯繫稍微有些分離。

4

在依賴注入範例,所有注入的對象必須在注入容器的控制,這是該容器實際上可以注入一個對象的一個​​實例爲注入點@Inject註釋)的唯一方式。

當實例化使用new操作對象實例,然後該對象實例是從注射容器的控制的(它是由所創建,而不是容器)。因此,即使在新對象實例中有注入點,容器也不會注意到它們,因此它不能將任何注入候選注入該對象實例的注入點(因爲,正如我已經說過的那樣,它是脫離其控制)。

因此,用幾句話回答:是的,如果您希望自動注入它們,您需要將所有對象都放在容器(Guice)的控制下。任何你可能想出來的注入方式在你的問題中按照你的意思進行操作將破壞Inversion of Control的規則。