subcut

subcut

https://github.com/dickwall/subcut

ドキュメント

トラブル

super constructor cannnot be passed a self reference unless parameter is declared by-name

というコンパイルエラーが発生する場合がある。Getting Startedを多少アレンジして、以下のようなコードを記述した場合。

trait WebSearch {  }
class GoogleSearchService()(implicit val bindingModule: BindingModule) extends WebSearch with Injectable {}

....
  object ProjectConfiguration extends NewBindingModule({ module =>
    module.bind [WebSearch] toLazyInstance { new GoogleSearchService()(ProjectConfiguration) }
  }) 

おそらく、以前のバージョンのScalaでは正常だったのだろうが、最新2.9.1ではエラーになってしまう。 これはhttps://issues.scala-lang.org/browse/SI-5000でバグとして報告されている。 ごく簡単にこれを発生させるコードは以下。

class Bar(fn: => Unit)
class Foo(val bar: Bar)
object Sample extends Bar(new Foo(Sample))

とりあえず、以下のようにして回避することはできる。

  object ProjectConfiguration extends NewBindingModule({ module =>
    module.bind [WebSearch] toLazyInstance { new GoogleSearchService()(getProjectConfiguration) }
  }) 
  
  def getProjectConfiguration = ProjectConfiguration

ソース

バイナリ非互換性

scalaのバイナリ非互換性のため、コンパイル済jarとしては2.8.0用、2.8.1用、2.9.0用が用意されている。

http://scala-tools.org/repo-releases/org/scala-tools/

TIPS

Injectableトレイトを継承したくないときのインジェクタ

通常は

class Sample()(implicit val bindingModule: BindingModule) extends Injectable {
  val something = inject[Something]
}

などとするが、これではInjectableのメソッドはすべて公開されてしまう。 bindingModuleが入手できるのであれば、プライベートなインジェクタを以下のようにして作成してもよい

class Sample()(implicit val bindingModule: BindingModule) {
  val injector = new Injectable { val bindingModule = Sample.this.bindingModule }
  val something = injector.inject[Something]
}

評価

last edited 2011-10-28 05:05:51 by ysugimura