11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

高階型の型パラメータを持つDDDリポジトリをDIできるようにする

Last updated at Posted at 2018-09-08

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をやる方は、まず間違いなくこの機能を使いたくなるはずです…。

  1. 要望を提案したら対応してもらいました! https://github.com/wvlet/airframe/pull/244

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?