1

さて、次のコードは失敗します。ただし、View の潜在的なインスタンスが複数ある場合、それらを使用したい場所に多数の Provider プロバイダーを挿入するのは扱いにくいと感じます。私の場合は可能かもしれませんが、他の場合はこれがうまくいかないことも想像できます. まだ試していない解決策の 1 つは、ダミーの @Assisted 引数をメソッドに追加して factory.getView1(null) のように呼び出すことですが、これもあまり良くありません。

注: Guice の実装者にとって、これがまれなケースになる理由はわかります。なぜなら、guice はコンストラクターを呼び出すのではなく (そうであるように)、代わりに (技術的に認識されている) プロバイダーを使用する必要があるからです。それでも、解決策がないと仮定するよりも、解決策があるかどうかを尋ねる方が適切です。:-)

import com.google.inject.*;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.FactoryModuleBuilder;
import junit.framework.Assert;
import org.junit.Test;


public class GuiceTests {

    static class View1 implements Presenter.View {
        String name = null;
        @Override
        public String getName() { return null; }
        public void setName(String name) { this.name = name ;}
    }
    static class View2 extends View1 {}
    static class Presenter {
        interface View {public String getName();}
        @Inject
        public Presenter(@Assisted View view //, and other injected services
        ){}
    }

    interface Factory{
        Presenter getPresenter(Presenter.View view);
        View1 getView1();
        View2 getView2();
    }

    static class Module extends AbstractModule
    {
        @Provides View1 getView1()
        {
            View1 view1 = new View1(); //or possibly get this from an xml generator
            view1.setName("buddy");
            return view1;
        }

        @Override
        protected void configure() {

            install(new FactoryModuleBuilder().implement(Presenter.class, Presenter.class)
                    .build(Factory.class));
        }
    }

    /**
     * We're testing the ability here for assisted injected factories
     * to be used to produce entities provided by the module with NO
     * assisted arguments. This way they can conveniently be used in
     * conjuction with other factory assisted methods as shown below.
     * This fails!
     */
    @Test
    public void testAssisted()
    {
        Injector injector = Guice.createInjector(new Module());

        Factory factory = injector.getInstance(Factory.class);
        View1 view1 = factory.getView1();
        Assert.assertEquals("buddy", view1.getName());
        Presenter presenter = factory.getPresenter(view1);

    }
}

追加のコンテキスト

アランは以下に尋ねました「これを使用する(インジェクターを呼び出さない)実際のコードの例を教えてくださいそれを行ったプレゼンターのフレーバーごとにメソッドを提供します)」

そのため、フローティング レイアウトのカードとして視覚化されたプレゼンターがあります。このプレゼンターには、一連のサービスを使用して自身を構成する特定のビジネス ロジックがあります。アプリには「新規」ボタンがあり、新しいプロセス (カードの構成) を案内するカードのビューを提供します。カードが構築されると、カードを表す別のビューがあります...しかし、同じビジネスロジックの多くを共有しています...したがって、理想的には、モデルで既に構成されているプレゼンターを再利用したい..しかし、今は添付します構築されたビュー。永続化されたカードは、ビルド ビューで再作成されます。その議論に従っていない限り、読まないでください。

上記のコードは、私が抱えている問題を適切に抽出していることに注意してください。以下は、より完全なコンテキストを提供するため、物事を複雑にします。

//----------------

//on Add new entity
cardLayout.add(factory.getPresenterWithWizardView());

//-----------
//then later in the finish of the wizard
thePresenter.setView(factory.getConstructedView());
//I would prefer not to create a new presenter here, as the presenter also has layout
//state and logic that maintains and interacts with cardLayout to . Allowing for removing
//and adding a different presenter would trigger stuff affecting the state.

//--------------
//however elsewhere cards are loaded with 
cardLayout.add(factory.getPresenterWithBuiltView(cardFromDb));
4

2 に答える 2

0

プレゼンターが必要な特定のビューがあることがわかっている場合は、次のようにモジュールに追加します。

@Provides @Named("PresenterForView1")
public Presenter forView1(Factory factory, View1 view1) {
  return factory.getPresenter(view1);
}

(名前ではなく適切な注釈を付けて、さまざまな既定のビューを繰り返します。)

後でプレゼンターのビューを変更したい場合は、そのビューを挿入するだけです。

@Inject Constructor(@Named("PresenterForView1") Presenter presenter, View2 view2) {
  ...
  presenter.setView(view2);
  ...
}

Provider<View2>(または、事前に構築したくない場合は、注入することもできます。)

于 2014-05-10T15:53:09.967 に答える
0

したがって、多くのプロバイダーを直接使用する (必要に応じて注入する) 以外に、factory.getPresenterWithView1() のようなメソッドを持つ SanerFactory クラスを作成する方法もあると思います。これは、View1 および View2 実装の使用を直接分離して、複数のプロバイダーを挿入する必要がある唯一の場所です。維持するボイラープレートが増えるのは残念です。

于 2014-05-10T13:57:39.330 に答える