1

私はGuiceにかなり慣れていないので、これが明白な質問ではないことを願っています...

Cリフレクションを使用してアプリケーションクラスの1つ(それを呼びましょう)を動的にインスタンス化するフレームワークを扱っているので、そのインスタンス化を制御することはできません。Cさらに、フレームワークがインスタンス化した後で新しく作成されたものにアクセスする簡単な方法はありません。これがどのCように見えるかです:

    パブリッククラスCはIを実装します{

        public C(){
            //このctorはフレームワークによって呼び出されるので、ここでDIを使用できませんか?
        }        

        public void initialize(){
            //これはf/wが呼び出すインスタンス化後のフックです
        }

        private void m(){
            依存関係d=Dependency.getInstance();
            d.doSmth();
        }
    }

DIを使っCて取得したいのですが。Dependencyこれは明らかにシングルトンDependencyですが、これは一般的にそうである必要はありません。

私は2つの可能な解決策を考え出しましたが、どちらも非常に整頓されているとは感じないので、専門家に聞いてみようと思いました。

  1. 静的注入。ただし、これがサービスロケーターのアンチパターンよりも大幅に向上するかどうかを確認するのに苦労しています。最終的には、外部から操作できる非最終的な静的フィールドになります...うーん。

  2. Cフレームワークは、インスタンス化後に自身を初期化するためのフックをサポートしています(initialize()上記の方法)。このメソッドは、セッターインジェクションを使用して新しく作成されたインスタンスをセルフインジェクトでき​​ます。

2の場合、これはより多くの外部変更可能性を意味すると思いますが、少なくとも単体テストなどの依存関係をもう少し明示的に公開します。問題は次のとおりです。その場合、どうすればGuice Injectorを手に入れることができますか(さらに別のサービスロケーターに依存することはできません)。また、アプリコード全体でインジェクターを明示的に参照することは疑わしい慣行であることも読みました(そして同意する傾向があります)。

あなたの洞察は本当にありがたいです。

どうもありがとう、
クリスチャン

4

2 に答える 2

2

プロバイダーをCに静的に注入してみることができます。静的注入はテストがより厄介です。しかし、プロバイダーは、Guiceが依存関係を怠惰に作成しながら、熱心に検証することを可能にします。

public class C implements I {
  @Inject static Provider<Dep1> dep1Provider;
  @Inject static Provider<Dep2> dep2Provider;

  ...

  public void initialize() {
    Dep1 dep1 = dep1Provider.get();
    Dep2 dep2 = dep2Provider.get();
    ...
  }
}
于 2011-03-17T07:03:08.633 に答える
1

Guiceインジェクターを静的変数および静的アクセサーメソッドで使用できるようにすると、次のように解決できます。

public class C implements I {

    public C() {
        // this ctor is invoked by the framework, you can't do injection here.
    }        

    public void initialize() {
        MyGuice.getInjector().inject(this);
    }

    @Inject
    protected void init(Dep1 dep1, Dep2 dep2) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    private void m() {
        dept1.doSmth();
    }
}

静的呼び出しは少しアンチパターンです。コードウィービングまたはポストコンパイルステップを実行するソリューションを使用する場合は、ポストコンストラクターインジェクションを処理する単純なアノテーションを使用してその依存関係を削除できます。このようにして、初期化メソッドがない場合でも、すべてのオブジェクトを挿入できます。この例はここにあります:AspectJでモデルオブジェクトを注入する方法

@Configurable
public class C implements I {

    public C() {
        // this ctor is invoked by the framework, you can't do injection here.
    }        

    @Inject
    protected void init(Dep1 dep1, Dep2 dep2) {
        this.dep1 = dep1;
        this.dep2 = dep2;
    }

    private void m() {
        dept1.doSmth();
    }
}
于 2011-03-20T20:35:46.357 に答える