简体   繁体   English

DI在Scala与蛋糕模式

[英]DI in Scala with Cake Pattern

This article explains Dependency Injection via Scala's Cake Pattern . 本文通过Scala的Cake Pattern解释了依赖注入。

My understanding of this pattern's benefit is that traits can be mixed in (production v. test) with static checking. 我对这种模式的好处的理解是,特征可以与(生产对测试)混合使用静态检查。

In Mr. Bonér's example, he lists this finished (per example) code: 在Bonér先生的例子中,他列出了这个完成的(每个例子)代码:

UserRepositoryComponent and UserServiceComponent UserRepositoryComponentUserServiceComponent

I added comments per my understanding. 我根据我的理解添加了评论。

trait UserRepositoryComponent {
  val userRepository: UserRepository    // stand-alone component

  class UserRepository {      
    ...                      // actual implementation here
  }
} 
trait UserServiceComponent { 
  this: UserRepositoryComponent =>      //Requires a mixed-in UserRepo*Component

  val userService: UserService  

  class UserService {
    ...                      // actual implementation here
  }
}

My understanding is that the Service depends on injection of a Repository component. 我的理解是Service依赖于注入Repository组件。

For production purposes, the following can be used to wire a "production" Repository component into the UserServiceComponent : 出于生产目的,可以使用以下内容将“生产” Repository组件连接到UserServiceComponent

object ComponentRegistry extends 
  UserServiceComponent with 
  UserRepositoryComponent 
{
  val userRepository = new UserRepository
  val userService = new UserService
}

If our production code wanted to use the userRepository or userService , is the correct way to use them via a simple import ? 如果我们的生产代码想要使用userRepositoryuserService ,那么通过简单import使用它们的正确方法是什么?

I think that I understand half of the article up to this point, but I'm not sure how to use the ComponentRegistry object. 到目前为止,我认为我理解文章的一半,但我不确定如何使用ComponentRegistry对象。

You're running head first into the bakery of doom bro: What are some compelling use cases for dependent method types? 你首先进入了厄运兄弟的面包店: 依赖方法类型的一些引人注目的用例是什么?

To answer your question, the proper way to use userService would be to use another trait and cake it up: 要回答你的问题,使用userService的正确方法是使用另一个特性并将其搞砸:

trait Example { this: UserServiceComponent => 
   def getExampleUser() = userService.getUser("ExampleUser")
}

Now whatever this new trait does isn't directly coupled to anything like the object ComponentRegistry . 现在无论这个新特性做什么都没有直接耦合到像ComponentRegistry这样的对象。 Instead your application becomes this: 相反,您的应用程序变为:

object Application extends 
  Example with
  UserServiceComponent with 
  UserRepositoryComponent 
{
  val userRepository = new UserRepository
  val userService = new UserService
}

Anyway, you should run for the hills because if you really want to use cake you should be doing something more like this: 无论如何,你应该跑到山上,因为如果你真的想要使用蛋糕,你应该做更像这样的事情:

trait UserRepositoryComponent {

  type UserRepository <: UserRepositoryLike

  val userRepository: UserRepository

  trait UserRepositoryLike {
    def getUserOrSomething()
  }

}

trait UserRepositoryComponentImpl extends UserRepositoryComponent {

  type UserRepository = UserRepositoryImpl
  val userRepository = new UserRepositoryImpl

  class UserRepositoryImpl extends UserRepositoryLike {
    override def getUserOrSomething() = ???
  }

}

trait UserServiceComponent {
  this: UserRepositoryComponent =>

  type UserService <: UserServiceLike
  val userService: UserService

  trait UserServiceLike {
    def getUserNameById(id: Int): String
  }

}

trait UserServiceComponentImpl extends UserServiceComponent {
  this: UserRepositoryComponent =>

  type UserService = UserServiceImpl
  val userService = new UserServiceImpl

  class UserServiceImpl extends UserServiceLike {
    override def getUserNameById(id: Int) = userRepository.getUserOrSomething
  }

}

trait Example {
  this: UserServiceComponent =>

  def getExampleUser() = userService.getUserNameById(1)

}

object Application extends
Example with
UserRepositoryComponentImpl with
UserServiceComponentImpl

Now save yourself some time, drop the cake pattern, and do something simple . 现在节省一些时间,放下蛋糕模式,做一些简单的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM