質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

Play Framework 2

Play Framework 2はPlayのメジャーバージョンです。現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。

Q&A

解決済

1回答

3419閲覧

Playframework Scala InjectionのController外からの直接利用について

Sakaeda1112

総合スコア22

Scala

ScalaはJava仮想マシンで動作を行うオブジェクト指向型プログラミング言語の1つです。静的型付けの関数型言語で、コンパイルエラーの検出に強みがあります。

Play Framework 2

Play Framework 2はPlayのメジャーバージョンです。現代の web アプリケーション開発に必要なコンポーネント及び API を統合した生産性の高い Java と Scala の web アプリケーションフレームワークです。

0グッド

1クリップ

投稿2016/08/29 07:32

編集2016/08/29 07:40

久しぶりにPlayframeworkを使ってみたら、DIを本格的に導入していて、慌ててDIってなんだ?と格闘しています。

PlayframeworkでInjectを利用する例が、ControllerでのInjectしか見当たらないのですが、
modelやその他クラスから直接Injectを利用する方法はないのでしょうか?

例えばSampleクラス内のexecメソッドでInjectされたserviceオブジェクトを参照したい場合、
現在以下のようにController経由で渡す方法しか分からないのですが、
execメソッド内で直接serviceオブジェクトを取得する方法はないものでしょうか?

scala

1 2class SampController @Inject()(service:Service) extends Controller{ 3 def index = Action{implict request => 4 #略 5 sample.exec(service) 6 ...7 } 8} 9 10class Sample{ 11 def exec(service:Service) = { 12 #略 serviceを使った何らかの処理 13 } 14}

これを以下の様な書き方にしたいです。

scala

1class SampController extends Controller{ 2 def index = Action{implict request => 3 #略 4 sample.exec() 5 ...6 } 7} 8 9class Sample{ 10 def exec = { 11 val service:Service = #なんらかの方法でInjectで取得する 12 #略 serviceを使った何らかの処理 13 } 14}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Playは今はほとんど使ってないので、他の環境のDIといくつかの資料を参考にしつつ、とりあえずこんな感じかなという実行例を書いてみました。
参考リンクは特に参考になったものを貼っています。

検証にはActivator 1.3.10, Google Guice 4.0を使用しています。

  • controllers/Application.scala

lang

1package controllers 2 3import play.api.mvc.{Action, Controller} 4import modules._ 5 6object Application extends Controller { 7 def index = Action { 8 val sample = new Sample() 9 Ok(views.html.index("Hello Play Framework: message=" + sample.exec())) 10 } 11} 12 13class Sample extends MyServiceModuleInjector { 14 def exec(): String = { 15 return service.getMessage() 16 } 17} 18 19trait MyService { 20 def getMessage(): String 21} 22 23object MyServiceImpl extends MyService { 24 def getMessage() = "MyServiceImpl!" 25}
  • modules/MyServiceModule.scala(新規追加)

lang

1package modules 2 3import controllers._ 4import com.google.inject.{AbstractModule, Guice} 5 6trait MyServiceModuleInjector { 7 protected val injector = Guice.createInjector(new MyServiceModule) 8 protected val service = injector.getInstance(classOf[MyService]) 9} 10 11class MyServiceModule extends AbstractModule { 12 override def configure(): Unit = 13 bind(classOf[MyService]).toInstance(MyServiceImpl) 14}

objectになっている箇所に注意してください。

これに合わせて、MyServiceModuleのインジェクションを有効にするために、application.confplay.modules.enabled += "modules.MyServiceModule"を追記します。

参考リンク:

Play Framework 2.5でobjectにDependency Injection(DI)する - Qiita
http://qiita.com/harry0000/items/2d95cfaf7da9614e7c83

Play2.4のDIについて動作確認(Guiceの使い方) - Qiita
http://qiita.com/mtoyoshi/items/768a1a8ece5a9be7254e

投稿2016/08/29 14:48

編集2016/08/29 15:25
argius

総合スコア9388

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Sakaeda1112

2016/08/29 15:05

なるほど、確かにこれならControllerからでなくInjectオブジェクトにアクセスできそうですね。 ただ、objectに縛られることで使い勝手はどうなるかなあ。 (色々試してみないと自分には分からなそうです。) 実は、stackoverflowでも質問してみたところ playでguiceでのDIはcontroller経由でやるものだ、的なことを言われ、 そういうものなのかな、と思い出したところで。。 (http://stackoverflow.com/questions/39201169/) 結局どういう形でDIを使っていくのが綺麗なコードになるのか、分からなくなってきました。。 すみません、もうちょっと色々試してからベストアンサーを選びたいと思います。
argius

2016/08/29 15:32

きれいに書く方法と言われると自信がないですね。 ただ、Playでcontroller以外でDIというのはこれでいちおう達成できたので、 あとはPlayやDIの話では無くてScalaのクラスなどの書き方の話になるのではと思います。 > objectに縛られる 再度確認してみたところ、Sampleはclassでもできました。 MyServiceImplの方もできるかもしれません。 たとえばMyServiceModuleの中でobject MyServiceImplの代わりにnewしたものを渡すとか。 その場合Singletonの話にもなるので、継承などを上手く使うなどして工夫してみて下さい。 > playでguiceでのDIはcontroller経由でやるものだ 確かにそれはそうだと思います。 そこをあえてcontroller以外でという認識でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問