2012-06-30 29 views
22

Kısa bir süre önce, Dead-Simple Dependency Injection ve Dependency Injection Without the Gymnastics ile Mon'lerle DI hakkında görüşmeler gördüm ve etkilendim. Basit bir problem üzerinde uygulamayı denedim, ancak önemsiz bir şey olmadığı anda başarısız oldu.Bağımlılık Enjeksiyonu İçin Okuyucu Monad Kullanımı

  • şey bağlıdır bir sınıfın bağlı olan bir sınıf enjekte edilecek olan birden fazla değere bağlı olan bir sınıf enjekte edilecek nerede gerçekten bağımlılık enjeksiyon çalışan bir sürümünü görmek istiyorum aşağıdaki örnekte olduğu gibi

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

Ben sadece ücret beri okuyucuyu Monad kullanarak örnek bir uygulamasını görmek gerçekten yararlı olacaktır Doğru yönde bir itme eksik olduğumu.

Teşekkürler!

cevap

26

"okuyucu monad" böylece tüm yapmanız gereken size gereken her şeyi içeren bir argüman kabul, sadece Function1 olduğunu. Şimdi bu ortamda dayalı bir Duck inşa etmek istiyorsanız

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

type Env[A] = Config => A 

: Örneğin:

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

Ve sonra inşa bir Zoo buna dayanarak kolaydır:

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

Scalaz kullanma (veya kendi başınıza biraz işinizle), bazı sözdizimi nicellerinden yararlanabiliriz. c:

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

Örneğiniz için teşekkürler. Merak ediyorum, (ya da daha büyük projelerin farkında mısınız) bunu DI için bahar veya goolge guvenesi yerine mi kullanıyorsunuz? Deneyiminize göre tercih edilir mi? –

+2

Evet, bunu yaygın olarak kullanıyoruz ve çok tercih edilir. Eğer Baharı veya Guice'yi tekrar görürsem, çok yakında olacak. – Apocalisp

+0

@Apocalisp, bu çözümü http://stackoverflow.com/questions/12341867/how-to-avoid-dependency-injection-in-scala/12363015#12363015 adresine uygulamanıza yardımcı olabilir misiniz? –

İlgili konular