0

Guice and Play を使い始めたばかりなので、これは長いが基本的な質問だと思います。http://eng.42go.com/play-framework-dependency-injection-guice/のガイドを確認しましたが、コードが失敗する理由がわかりません。

まず、グローバル インジェクターがあります。

public class GlobalInjector {
    private static Injector guiceInjector;
    private static List<AbstractModule> modules = new ArrayList<AbstractModule>();

    public static Injector getInjector() {
        return guiceInjector;
    }

    public static loadModules() {
        guiceInjector = Guice.createInjector(modules);
    }

    public static addModule(AbstractModule module) {
        modules.add(module);
    }
}

GlobalSettingsまた、クラスを拡張して Guice to Play を追加しました(application.global も変更しました)。

public class GuiceExtendedSettings extends GlobalSettings {
    @Override
    public void onStart(Application app) {
        GlobalInjector.loadModules();
    }

    @Override
    public <A> A getControllerInstance(Class<A> controllerClass) {
         return GlobalInjector.getInjector().getInstance(controllerClass);
    }
}

次に、Play でプラグインとして機能するテスト モジュールを用意します (この記事では何もしないため、いくつかの必要なメソッドは省略されています)。

public class TestModule extends AbstractModule implements Plugin {

    @Override
    public void configure() {
        // Worker is a simple class
        Worker worker = new SimpleWorker();
        MapBinder<String, Worker> mapBinder = MapBinder.newMapBinder(binder(), String.class, Worker.class);
        mapBinder.addBinding(worker.getName()).toInstance(worker);
    }

    @Override
    public void onStart() {
        GlobalInjector.addModule(this);
    }
}

Workerシンプルなインターフェースです:

public interface Worker {
    public String getName();
    public String getResult();
}

SimpleWorker:

public class SimpleWorker implements Worker {
    public String getName() {
        return "SimpleWorker";
    }

    public String getResult() {
        return "works";
    }
}

そして、ここにコントローラーのロジックを示すコード部分があります: 注入されたマップにすべてのワーカーの結果を出力するだけです

public class TestController extends Controller {
     @Inject
     Map<String, Worker> workers;

     public Result showWorkers() {
         StringBuilder sb = new StringBuilder();
         for (Worker worker : workers) {
             sb.append(worker.getName() + ": " + worker.getResult() + "</br>");
         }
         return ok(sb.toString()).as("text/html");
     } 
}

わかった。これを機能させるために、次の行を play.plugins に追加しました。

100:test.TestModule

私の考えは: Play がプラグイン (TestModule) をロードする -> TestModule が GlobalInjector に自身を追加する -> GlobalInjector が Guice インジェクターを作成する -> Guice がマップをコントローラーに注入する

しかし、その結果、 Guice はマップを挿入しませんでした。地図はまだnullです。

また、どのようにテストすればよいですか?(つまり、どうすればそのマップにさまざまなワーカーを注入できますか?上記のコードでその部分をハードコードしました。しかし、さまざまなモジュールを使用して動的な方法を探しています。)

public class Test {
    @Test
    public void testInjector() {
        running(fakeApplication(), new Runnable() {
           public void run() { 
               // how can I inject using different modules here?
           }
        });

    }
} 
4

1 に答える 1

1

グローバル設定オブジェクトと追加のプラグインの両方を指定できるようにする fakeApplication ヘルパー メソッドを使用する必要があります。http://www.playframework.com/documentation/api/2.1.x/java/play/test/Helpers.html#fakeApplication(java.util.Map,%20java.util.List,%20play.GlobalSettings)を参照してください。詳しくは。

しかし、基本的に、テストは次のようになります。

public class Test {
    @Test
    public void testInjector() {
       Map<String, Object> config = new HashMap<String, Object>();
       // add any additional config options, e.g. in-memory db
       List<String> plugins = new ArrayList<String>();
       plugins.add("full.package.name.TestModule");
       GlobalSettings global = null;
       try {
           global = (GlobalSettings) Class.forName("full.package.name.GuiceExtendedSettings").newInstance();
       } catch(Exception e) {}

       running(fakeApplication(config, plugins, global), new Runnable() {
           public void run() { 
               // do some assertions
           }
        });
    }
}

また、guice がテスト コントローラーをインスタンス化するか、ワーカー マップが挿入されないようにする必要があります。

于 2013-08-08T20:40:29.053 に答える