views:

363

answers:

3

Hi,

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

+2  A: 

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] => ...
}
Dirk
Yes, already loving the `Option`, `Some` and `None`!
puudeli
+5  A: 

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
  }
}
Mitch Blevins
+1: Nice. Didn't know that. Thought, the `Option` class was the way to "emulate" `null`.
Dirk
Using `Option` is a better way if you actually have to work with `null`/`None` values; if you just need to initialize using setter methods, there is nothing wrong with using `null`.
Alexey Romanov
Greenfield code would avoid null altogether using `Option`, but @puudeli specifically said he was integrating with existing java code.
Mitch Blevins
I believe that the underscore reads better than an explicit null (even for non-Parameterized code) because an underscore is commonly used to refer to "something to be filled in later" in other domains.
Mitch Blevins
Thanks! `_` seems to be quite magical :-)
puudeli
+3  A: 

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.

mkneissl
Thx, I have read Jonas' article, you recalled correctly, it does not cover setter based injection :-)
puudeli