scala - Uso de Reader Monad para inyección de dependencia
dependency-injection functional-programming (1)
La "mónada del lector" es solo la Function1
, por lo que todo lo que debe hacer es aceptar un argumento que contenga todas las cosas que necesita. Por ejemplo:
trait Config {
def fly: FlyBehaviour
def quack: QuackBehaviour
}
type Env[A] = Config => A
Ahora si quieres construir un Duck
basado en este entorno:
val a: Env[Animal] = c => new Duck(c.fly, c.quack)
Y luego construir un Zoo
basado en eso es fácil:
val z: Env[Zoo] = a andThen (new Zoo(_))
Utilizando Scalaz (o con un poco de trabajo por su cuenta) puede hacer uso de algunas sintaxis para "pedir" la configuración c
:
val z: Env[Zoo] = for {
c <- ask
} yield new Zoo(Duck(c.fly, c.quack))
Recientemente vi las conversaciones Inyección de dependencia simple-muerta e inyección de dependencia sin gimnasia sobre DI con mónadas y me impresionó. Traté de aplicarlo en un problema simple, pero fallé tan pronto como se volvió no trivial. Realmente me gustaría ver una versión de inyección de dependencia en ejecución donde
- Una clase que depende de más de un valor que debe inyectarse.
- una clase que depende de una clase que depende de algo para ser inyectado
como en el siguiente ejemplo
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()
Sería muy útil ver una implementación de ejemplo utilizando el lector Monad, ya que siento que me falta un impulso en la dirección correcta.
¡Gracias!