Tied up with injection implemented with setter functions
I'm trying to use Scala as part of an existing Java application and now I run into an issue with dependencies injected with a setter method (no DI frameworks in this part of code). How is this handled in a Scala way?
In Scala both val开发者_如何学Go
and var
require to be initialized when declared but I can't do that, since the Java setters inject objects that implement a certain interface and interfaces are abstract and can not be instantiated.
class ScalaLogic {
var service // How to initialize?
def setService (srv: OutputService) = {
service = srv
}
Is there a way to initialize the var service
so that I can later assign a dependency into it? It should be lexically scoped to be visible in the whole class.
You can initialize to a default (null) using an underscore.
class ScalaLogic {
var service: OutputService = _
def setService (srv: OutputService) = {
service = srv
}
}
The nice thing about the underscore (as opposed to just using null) is that it works with both primitives and objects, so parameterized classes work like this:
class ScalaLogic[T] {
var service: T = _
def setService (srv: T) = {
service = srv
}
}
One of the many meanings of the underscore is to mark a variable as uninitialized. So if you want an uninitialized field, initialize it with _ .
To have getters and setters for a field annotate it with @BeanProperty. The compiler will generate the Java-Style getter and setter for you.
import reflect.BeanProperty
class ScalaLogic {
@BeanProperty
var service: OutputService = _
}
By the way, the canonical reference to Dependency Injection in Scala is the summary by Jonas Bonér. This article does not cover setter-based injection, though, if I recall correctly.
Try using class Option
. This is the moral equivalent of using null
in Java. Declare the service like so:
var service: Option[MyInterface] = None
and use
service.get()
or pattern matching
service match {
case None => ...
case Some[MyInterface] => ...
}
精彩评论