【问题标题】:Using Reader Monad for Dependency Injection使用 Reader Monad 进行依赖注入
【发布时间】:2012-06-30 17:52:54
【问题描述】:

我最近看到了 Dead-Simple Dependency InjectionDependency Injection Without the Gymnastics 与 Monads 关于 DI 的会谈,印象深刻。我试图将它应用于一个简单的问题,但一旦它变得不平凡就失败了。我真的很想看到依赖注入的运行版本在哪里

  • 依赖于多个必须注入的值的类
  • 一个依赖于某个类的类,该类依赖于要注入的东西

如下例所示

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

谢谢!

【问题讨论】:

    标签: scala dependency-injection functional-programming monads


    【解决方案1】:

    “reader 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)
    

    然后在此基础上构造一个Zoo 很容易:

    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))
    

    【讨论】:

    • 感谢您的示例。我很好奇,您(或者您是否知道任何更大的项目)使用它来代替弹簧或 DI 的 goolge guice?根据您的经验,它更可取吗?
    • 是的,我们正在广泛使用它,而且它更可取。如果我再次看到 Spring 或 Guice,那就太早了。
    • @Apocalisp,你能帮我把这个解决方案应用到stackoverflow.com/questions/12341867/…吗?
    • 我对最后一个例子有点困惑。 ask 返回 Reader[Config, Config],但随后 new Duck... 返回 Duck,不是吗?我想它是如何神奇地变成Reader[Config, Duck]?或者它的意思是阅读a = new Duck...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 2015-09-26
    • 2014-01-19
    • 2014-03-25
    • 2019-11-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多