带蛋糕图案的Scala DI
这解释了通过Scala的带蛋糕图案的Scala DI,scala,dependency-injection,Scala,Dependency Injection,这解释了通过Scala的蛋糕模式进行依赖注入的原因 我对这种模式的好处的理解是,特性可以与静态检查混合在一起(生产测试) 在Bonér先生的例子中,他列出了完成的(每个例子)代码: UserRepositoryComponent和UserServiceComponent 我根据我的理解添加了评论 trait UserRepositoryComponent { val userRepository: UserRepository // stand-alone component c
蛋糕模式进行依赖注入的原因
我对这种模式的好处的理解是,特性可以与静态检查混合在一起(生产测试)
在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
}
}
我的理解是服务
依赖于存储库
组件的注入
出于生产目的,可以使用以下命令将“生产”存储库组件连接到UserServiceComponent
:
object ComponentRegistry extends
UserServiceComponent with
UserRepositoryComponent
{
val userRepository = new UserRepository
val userService = new UserService
}
如果我们的生产代码想要使用用户存储库
或用户服务
,那么通过简单的导入
使用它们是否正确
到目前为止,我想我已经理解了这篇文章的一半内容,但我不知道如何使用ComponentRegistry
对象。您正在头朝下跑进doom bro的面包店:
要回答您的问题,正确使用userService
的方法是使用另一个特性并将其简化:
trait Example { this: UserServiceComponent =>
def getExampleUser() = userService.getUser("ExampleUser")
}
现在,这个新特性所做的任何事情都不会直接耦合到对象ComponentRegistry
之类的东西。相反,您的应用程序变为:
object Application extends
Example with
UserServiceComponent with
UserRepositoryComponent
{
val userRepository = new UserRepository
val userService = new UserService
}
无论如何,你应该向山上跑去,因为如果你真的想用蛋糕,你应该做更多类似的事情:
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
trait UserRepositoryComponent{
类型UserRepository
类型用户服务
类型UserService=userserviceinpl
val userService=new userserviceinpl
类UserServiceImpl扩展了UserServiceLike{
覆盖def getUserNameById(id:Int)=userRepository.getUserOrSomething
}
}
特征示例{
此:UserServiceComponent=>
def getExampleUser()=userService.getUserNameById(1)
}
对象应用程序扩展
以身作则
带的UserRepositoryComponentMPL
UserServiceComponentMPL
现在,为自己节省一些时间,放弃蛋糕模式,做点什么。有一天,人们会停止为DI设计bs模式,回到争论中去。我想相信…我会回到厄运面包店吗?推荐