DDDリポジトリを楽に実装するライブラリで紹介したscala-ddd-baseを使って実装したリポジトリをairframeを使ってDIする事例を簡単に紹介します。
リポジトリの実装は前回の記事のとおりです。UserAccountRepositoryは高階型の型パラメータM[_]を必要とします。 この例では、Task[A]のタイプエイリアスとしてBySlick[A]を宣言し、ファクトリメソッドで実装を生成できるようにしています。
object UserAccountRepository {
type BySlick[A] = Task[A]
def bySkinny: UserAccountRepository[BySkinny] = new UserAccountRepositoryBySkinny
}
class UserAccountRepositoryBySkinny
extends UserAccountRepository[BySkinny]
...
airframe 0.64から高階型でもバインディングを設定できる1ので、以下のように型に対するインスタンスを指定します。
val design = newDesign.bind[UserAccountRepository[BySkinny]].toInstance(UserAccountRepository.bySkinny)
インスタンスを得る方法はこれまでどおり型を指定するだけです。
val resultFuture = design.withSession{ session =>
val repository = session.build[UserAccountRepository[BySkinny]]
(for {
_ <- repository.store(userAccount)
result <- repository.resolveById(userAccount.id)
} yield result).run(AutoSession).runAsync
}
実際に動作するコードはこちらです
タイプエイリアスとか高階型を利用するなら、airframeの方が便利そうです。Tagless Finalをやる方は、まず間違いなくこの機能を使いたくなるはずです…。
-
要望を提案したら対応してもらいました! https://github.com/wvlet/airframe/pull/244 ↩