Skip to content

Instantly share code, notes, and snippets.

@j5ik2o
Last active September 7, 2018 17:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save j5ik2o/27893af03914aea29a9de4fd10e1f51f to your computer and use it in GitHub Desktop.
Save j5ik2o/27893af03914aea29a9de4fd10e1f51f to your computer and use it in GitHub Desktop.

型パラメータが高階型の場合のDIについて

トレイト: UserAccountRepository[M[_]] https://github.com/j5ik2o/scala-ddd-base/blob/master/example/src/main/scala/com/github/j5ik2o/dddbase/example/repository/UserAccountRepository.scala

実装: UserAccountRepositoryBySkinny https://github.com/j5ik2o/scala-ddd-base/blob/master/example/src/main/scala/com/github/j5ik2o/dddbase/example/repository/skinny/UserAccountRepositoryBySkinny.scala

があったとして、以下のようなDIをさせたいのですが、

val design = newDesign.bind[UserAccountRepository[BySkinny]].toInstance(UserAccountRepository.bySkinny)

以下のようなエラーが発生します。サポート外ですかね? けっこうScalaならではの使い方なのでサポートしてくれると、他のコンテナより優位かもですが…階数とか考えるとめんどいですかね…。

An exception or error caused a run to abort: Surface com.github.j5ik2o.dddbase.example.repository.UserAccountRepository.BySkinny is not found in cache 
java.lang.IllegalArgumentException: Surface com.github.j5ik2o.dddbase.example.repository.UserAccountRepository.BySkinny is not found in cache
	at wvlet.surface.reflect.SurfaceFactory$$anonfun$get$1.apply(SurfaceFactory.scala:53)
	at wvlet.surface.reflect.SurfaceFactory$$anonfun$get$1.apply(SurfaceFactory.scala:53)
	at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
	at scala.collection.AbstractMap.getOrElse(Map.scala:59)
	at wvlet.surface.reflect.SurfaceFactory$.get(SurfaceFactory.scala:53)
	at wvlet.surface.package$.getCached(package.scala:28)
	at wvlet.surface.LazySurface.ref(Surfaces.scala:206)
	at wvlet.surface.LazySurface.params(Surfaces.scala:217)
@xerial
Copy link

xerial commented Sep 7, 2018

Airframe handles type aliases (BySkinny[A]) and de-aliased types (UserAccountRepository[BySkinny]) differently, so this code should be written like:

newDesign
  .bind[BySkinny].toInstance(UserAccountRepository.bySkinny)

For example, in a simple example, using higher kind types has no problem:
https://github.com/wvlet/airframe/blob/ada217700274c88ab7bddde43f678483c71ff393/airframe/src/test/scala/wvlet/airframe/HigherKindTypeTest.scala

It seems this error is happening when traversing recursive types. I guess when traversing type aliases, Airframe should traverse de-aliased types as well.

@xerial
Copy link

xerial commented Sep 7, 2018

Successfully reproduced this error in wvlet/airframe#242.
I'm going to check the cause of this issue.

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment