2

Dependency Injection 全般の背後にある考え方、特に Guice の使用法を完全に理解しているかどうかはわかりません。

私はかなり大きなスイング アプリケーションを持っています。このアプリを切り離すために、guice を紹介したいと思います。メインクラスにインジェクターがあると仮定します

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

そして、それは機能します。JPanel などのフィールドが Application クラスにあり、@Inject で注釈が付けられている場合、それが注入されます。ただし、Application コンストラクターで何かを手動で作成した場合、例の 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

4

2 に答える 2

5

依存性注入パラダイムでは、注入されたすべてのオブジェクトは注入コンテナーの制御下にある必要があります。これは、コンテナーが実際にオブジェクトのインスタンスを注入ポイント(@Inject注釈付き) に注入できる唯一の方法です。

newオペレーターを使用してオブジェクト インスタンスをインスタンス化すると、そのオブジェクト インスタンスはインジェクション コンテナーの制御外になります(コンテナーではなく、ユーザーが作成したものです)。そのため、その新しいオブジェクト インスタンスに注入ポイントがあっても、コンテナーはそれらを認識しないため、そのオブジェクト インスタンスの注入ポイントに注入候補を注入することはできません (既に述べたように、制御不能)。

したがって、いくつかの単語で答えます。はい、それらを自動的に注入する場合は、すべてのオブジェクトをコンテナー (Guice) の制御下に置く必要があります。質問で意図した方法でインジェクションを機能させるために思いつく可能性のあるハックは、Inversion of Controlのルールに違反することになります。

于 2012-09-04T13:29:25.777 に答える
0

new を使用したい場合、または使用する必要がある場合は、 providers guice providersまたはオンデマンド インジェクション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);
      }

}

2 つの異なるパネルが挿入されているため、命名によってそれらを区別します。つまり、annotatedWith でバインドします。

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

または、Application コンストラクターで MyNewPanel を使用します。しかし、それはやや切り離されていません。

于 2012-09-04T13:20:13.787 に答える