मैं Play! Framework का उपयोग Scala के लिए लगभग एक साल से कर रहा हूं। मैं वर्तमान में संस्करण 2.5.x का उपयोग कर रहा हूं।प्ले फ्रेमवर्क में स्कैला के ऑब्जेक्ट पर @ सिंगलेटन का उपयोग क्यों करें?
मुझे प्ले में नियंत्रकों के विकास और कैसे डेवलपर्स को स्थिर object
मार्गों से दूर मजबूर किया गया है।
मुझे खेल में Guice उपयोग के बारे में भी पता है।
आप activator डाउनलोड करने और चलाते हैं:
activator new my-test-app play-scala
उत्प्रेरक आप के लिए एक टेम्पलेट परियोजना का उत्पादन करेगा। मेरा प्रश्न विशेष रूप से उस टेम्पलेट की this फ़ाइल के आसपास है।
मेरी परीक्षण एप्लिकेशन के अंतर्गत/ऐप्स/सेवाओं/Counter.scala
package services
import java.util.concurrent.atomic.AtomicInteger
import javax.inject._
/**
* This trait demonstrates how to create a component that is injected
* into a controller. The trait represents a counter that returns a
* incremented number each time it is called.
*/
trait Counter {
def nextCount(): Int
}
/**
* This class is a concrete implementation of the [[Counter]] trait.
* It is configured for Guice dependency injection in the [[Module]]
* class.
*
* This class has a `Singleton` annotation because we need to make
* sure we only use one counter per application. Without this
* annotation we would get a new instance every time a [[Counter]] is
* injected.
*/
@Singleton
class AtomicCounter extends Counter {
private val atomicCounter = new AtomicInteger()
override def nextCount(): Int = atomicCounter.getAndIncrement()
}
तुम भी this फ़ाइल में इसके उपयोग देख सकते हैं:
मेरी परीक्षण एप्लिकेशन के अंतर्गत/ऐप्स/नियंत्रकों /CountController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import services.Counter
/**
* This controller demonstrates how to use dependency injection to
* bind a component into a controller class. The class creates an
* `Action` that shows an incrementing count to users. The [[Counter]]
* object is injected by the Guice dependency injection system.
*/
@Singleton
class CountController @Inject() (counter: Counter) extends Controller {
/**
* Create an action that responds with the [[Counter]]'s current
* count. The result is plain text. This `Action` is mapped to
* `GET /count` requests by an entry in the `routes` config file.
*/
def count = Action { Ok(counter.nextCount().toString) }
}
यह हर नियंत्रक जो निर्माण किया है इसका मतलब है या @Inject() (counter: Counter)
का Counter
का एक ही उदाहरण प्राप्त होगा।
तो मेरे सवाल है:
क्यों @Singleton
का उपयोग करें और फिर इसे @Inject
एक नियंत्रक में, जब इस उदाहरण के लिए आप सिर्फ एक स्काला वस्तु इस्तेमाल कर सकते हैं?
इसका बहुत कम कोड है।
उदाहरण:
मेरी परीक्षण एप्लिकेशन के अंतर्गत/ऐप्स/सेवाओं/Counter.scala
package services
trait ACounter {
def nextCount: Int
}
object Counter with ACounter {
private val atomicCounter = new AtomicInteger()
def nextCount(): Int = atomicCounter.getAndIncrement()
}
यह इतना की तरह उपयोग करें:
मेरी परीक्षण एप्लिकेशन के अंतर्गत/ऐप्स/नियंत्रक/countController.scala
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import services.{Counter, ACounter}
/**
* This controller demonstrates how to use dependency injection to
* bind a component into a controller class. The class creates an
* `Action` that shows an incrementing count to users. The [[Counter]]
* object is injected by the Guice dependency injection system.
*/
@Singleton
class CountController extends Controller {
//depend on abstractions
val counter: ACounter = Counter
def count = Action { Ok(counter.nextCount().toString) }
}
क्या अंतर है? इंजेक्शन पसंदीदा है, और क्यों?
इससे कोई फर्क नहीं पड़ता कि आपको पैरामीटर पास करने की आवश्यकता नहीं है आपके नियंत्रक के लिए। लेकिन यदि आप करते हैं, तो इसे निर्भरता को इंजेक्ट करने और इंजेक्ट करने के लिए गुइस के लिए एक वर्ग होना आवश्यक है। –