3

一般的に、インジェクターはすべてのアプリケーションで1回だけ使用する必要があることを知っています(起動時)。しかし、私には次のユースケースがあります。Executorのタスク実装を注入すると、そのタスク内に依存関係(たとえばFileHandler)があり、毎回インスタンス化する必要があります。FileHandlerProvider私は、要求されるたびに新しいインスタンスを返すプロバイダー(たとえば)を注入する方法を知っています。問題はFileHandler、それ自体に多くの依存関係があることです(たとえばParserOutputPrinter...)。今では、それらも毎回新しいインスタンスを必要とします(実装にはカウンターなどの状態があり、次のスレッドの実行時に同じインスタンスを再利用することが問題になるため)。重要なのは、プロバイダーが注入された後、プロバイダーの同じインスタンスが再利用されるため、新しいFileHandlerものは常に同じもので作成されParserOuputPrinter。解決策は、パーサーとインの代わりにParserProvider インジェクトすることですが、それは正しくありません。依存関係が増えるため、すぐに複雑になりすぎます。私が今見ている唯一の簡単な解決策は、でInjectorを使用することです。これにより、新しいインスタンス(および依存関係の新しいインスタンス)が返されます。それとも、この状況で別のよりエレガントな解決策がありますか?OutputPrinterProviderOuputPrinterFileHandlerProviderFileHandlerProviderFileHandler

4

1 に答える 1

4

バインドFileHandlerとその依存関係はすべてデフォルトのスコープ(つまりスコープなし)で行う必要があります。次に、新しいインスタンスが必要になるたびに、そのインスタンスを挿入Provider<FileHandler>して使用します。スコープがないため、毎回新しいインスタンスを作成する必要があります...また、その依存関係にもスコープがないため、それぞれの新しいインスタンスも毎回作成する必要があります。それはあなたが望むように動作するはずです。get()FileHandlerFileHandlerget()FileHandler

ここで(多分)欠けているのは、これらのプロバイダーを自分で作成する必要がないということだと思います...注入するだけProvider<FileHandler>で、Guiceがすべてを行います。

編集:これは私が書いた小さなクラスで、そのクラスのインスタンスが作成されるたびに新しく作成されるクラスの依存関係を示しています。

public class Test {
  public static void main(String[] args) {
    Injector injector = Guice.createInjector();
    injector.getInstance(Test.class);
  }

  @Inject public Test(Provider<FileHandler> fileHandlerProvider) {
    FileHandler fileHandler1 = fileHandlerProvider.get();
    FileHandler fileHandler2 = fileHandlerProvider.get();

    System.out.println("fileHandler1 == fileHandler2? " + 
        (fileHandler1 == fileHandler2));
    System.out.println("fileHandler1.parser == fileHandler2.parser? " + 
        (fileHandler1.parser == fileHandler2.parser));
    System.out.println("fileHandler1.print == fileHandler2.printer? " + 
        (fileHandler1.printer == fileHandler2.printer));
  }

  private static class FileHandler {
    private final Parser parser;
    private final OutputPrinter printer;

    @Inject private FileHandler(Parser parser, OutputPrinter printer) {
      this.parser = parser;
      this.printer = printer;
    }
  }

  private static class Parser {
  }

  private static class OutputPrinter {
  }
}

実行すると、次のコードが出力されます。

fileHandler1 == fileHandler2?false
fileHandler1.parser == fileHandler2.parser?false
fileHandler1.print == fileHandler2.printer?false

これは、毎回新しいインスタンスが作成されただけでなく、FileHandler毎回新しいParserインスタンスOutputPrinterが作成されて注入されたことをFileHandler示しています。

于 2011-01-22T20:15:28.267 に答える