使用Reader Monad进行依赖注入 [英] Using Reader Monad for Dependency Injection

查看:127
本文介绍了使用Reader Monad进行依赖注入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近看到死亡简单依赖注入没有体操的依赖注射关于DI与Monads的DIY并且印象深刻。我试图将其应用于一个简单的问题,但一旦遇到不便,就失败。我真的想看到依赖注入的运行版本,其中

I recently saw the talks Dead-Simple Dependency Injection and Dependency Injection Without the Gymnastics about DI with Monads and was impressed. I tried to apply it on a simple problem, but failed as soon as it got non-trivial. I really would like to see a running version of dependency injection where


  • 依赖于多个值必须注入的类

  • 一个依赖于依赖于要注入的东西的类的类

以下示例

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查看示例实现真的很有帮助,因为我只是觉得我错过了正确的方向。

It would be really helpful to see a sample implementation using the reader Monad since I just feel that I am missing a push in the right direction.

谢谢!

推荐答案

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

The "reader monad" is just Function1, so all you need to do is accept an argument containing all the things you need. For example:

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

type Env[A] = Config => A

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

Now if you want to construct a Duck based on this environment:

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

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

And then constructing a Zoo based on that is easy:

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

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

Using Scalaz (or with a bit of work on your own) you can make use of some syntax niceties to "ask" for the config c:

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

这篇关于使用Reader Monad进行依赖注入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆