加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 使用Reader Monad进行依赖注入

发布时间:2020-12-16 09:44:25 所属栏目:安全 来源:网络整理
导读:我最近看到了与Monads的DI000会谈 Dead-Simple Dependency Injection和 Dependency Injection Without the Gymnastics,令人印象深刻。我试图将其应用于一个简单的问题,但一旦遇到不便,就失败。我真的想看到依赖注入的运行版本 一个依赖于多个值必须被注入
我最近看到了与Monads的DI000会谈 Dead-Simple Dependency Injection和 Dependency Injection Without the Gymnastics,令人印象深刻。我试图将其应用于一个简单的问题,但一旦遇到不便,就失败。我真的想看到依赖注入的运行版本

>一个依赖于多个值必须被注入的类
>一个依赖于要注入的东西的类的类

如下例所示

trait FlyBehaviour { def fly() }
trait QuackBehaviour { def quack() }
trait Animal { def makeSound() }

// needs two behaviours injected
class Duck(val flyBehaviour: FlyBehaviour,val quackBehaviour: QuackBehaviour) extends Animal 
{
   def quack() = quackBehaviour.quack()
   def fly() = flyBehaviour.fly()
   def makeSound() = quack()
}

// needs an Animal injected (e.g. a Duck)
class Zoo(val animal: Animal)

// Spring for example would be able to provide a Zoo instance
// assuming a Zoo in configured to get a Duck injected and
// a Duck is configured to get impl. of FlyBehaviour and QuackBehaviour injected
val zoo: Zoo = InjectionFramework.get("Zoo")
zoo.animal.makeSound()

使用读者Monad看到一个示例实现将是非常有帮助的,因为我只是觉得我错过了正确的方向。

谢谢!

解决方法

“读者monad”只是Function1,所以你需要做的只是接受一个包含所有你需要的东西的参数。例如:

trait Config {
   def fly: FlyBehaviour
   def quack: QuackBehaviour
}

type Env[A] = Config => A

现在,如果你想在这个环境下构建一个Duck:

val a: Env[Animal] = c => new Duck(c.fly,c.quack)

然后根据这个建立一个动物园很容易:

val z: Env[Zoo] = a andThen (new Zoo(_))

使用Scalaz(或者你自己的一些工作),你可以利用一些语法细节来“问”配置c:

val z: Env[Zoo] = for {
  c <- ask
} yield new Zoo(Duck(c.fly,c.quack))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读