相关疑难解决方法(0)

用于依赖注入的Reader Monad:多个依赖项,嵌套调用

当被问及Scala中的依赖注入时,很多答案都指向使用Reader Monad,无论是来自Scalaz还是只是自己编写.有很多非常明确的文章描述了这种方法的基础知识(例如,Runar的演讲,Jason的博客),但我没有设法找到更完整的例子,我没有看到这种方法的优势超过例如更多传统的"手动"DI(参见我写的指南).最有可能的是我错过了一些重要的观点,因此问题就出现了.

举个例子,我们假设我们有这些类:

trait Datastore { def runQuery(query: String): List[String] }
trait EmailServer { def sendEmail(to: String, content: String): Unit }

class FindUsers(datastore: Datastore) {
  def inactive(): Unit = ()
}

class UserReminder(findUser: FindUsers, emailServer: EmailServer) {
  def emailInactive(): Unit = ()
}

class CustomerRelations(userReminder: UserReminder) {
  def retainUsers(): Unit = {}
}
Run Code Online (Sandbox Code Playgroud)

在这里,我使用类和构造函数参数进行建模,这与"传统"DI方法非常相似,但是这个设计有几个好的方面:

  • 每个功能都清楚地枚举了依赖关系.我们假设确实需要依赖关系才能使功能正常工作
  • 依赖关系跨功能隐藏,例如,UserReminder不知道FindUsers需要数据存储.功能甚至可以在单独的编译单元中
  • 我们只使用纯Scala; 实现可以利用不可变类,高阶函数,IO如果我们想要捕获效果等,"业务逻辑"方法可以返回包含在monad中的值.

怎么能用Reader monad建模呢?保留上面的特性会很好,因此很清楚每个功能需要什么样的依赖关系,并隐藏一个功能与另一个功能的依赖关系.请注意,使用classes更多的是实现细节; 也许使用Reader monad的"正确"解决方案会使用其他东西.

我找到了一个有点相关的问题,暗示:

  • 使用具有所有依赖项的单个环境对象 …

dependency-injection scala scalaz

85
推荐指数
1
解决办法
6498
查看次数

标签 统计

dependency-injection ×1

scala ×1

scalaz ×1