Kev*_*ith 3 dependency-injection scala
该文章通过Scala的解释依赖注入Cake Pattern.
我对这种模式的好处的理解是,特征可以与(生产对测试)和静态检查混合在一起.
在Bonér先生的例子中,他列出了这个完成的(每个例子)代码:
UserRepositoryComponent和UserServiceComponent
我根据我的理解添加了评论.
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
}
}
Run Code Online (Sandbox Code Playgroud)
我的理解是,这Service取决于注射Repository成分.
出于生产目的,可以使用以下内容将"生产" Repository组件连接到UserServiceComponent:
object ComponentRegistry extends
UserServiceComponent with
UserRepositoryComponent
{
val userRepository = new UserRepository
val userService = new UserService
}
Run Code Online (Sandbox Code Playgroud)
如果我们的生产代码想要使用userRepository或userService,是否通过简单的方法使用它们import?
到目前为止,我认为我理解文章的一半,但我不确定如何使用该ComponentRegistry对象.
你首先进入了厄运兄弟的面包店: 依赖方法类型的一些引人注目的用例是什么?
要回答你的问题,正确的使用userService方法是使用另一个特性并将其搞砸:
trait Example { this: UserServiceComponent =>
def getExampleUser() = userService.getUser("ExampleUser")
}
Run Code Online (Sandbox Code Playgroud)
现在无论这个新特性做什么都不会直接耦合到像对象这样的东西ComponentRegistry.相反,您的应用程序变为:
object Application extends
Example with
UserServiceComponent with
UserRepositoryComponent
{
val userRepository = new UserRepository
val userService = new UserService
}
Run Code Online (Sandbox Code Playgroud)
无论如何,你应该跑到山上,因为如果你真的想要使用蛋糕,你应该做更像这样的事情:
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
Run Code Online (Sandbox Code Playgroud)
现在节省一些时间,放下蛋糕模式,做一些简单的事情.