puudeli
puudeli

Reputation: 719

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

Upvotes: 1

Views: 700

Answers (3)

mkneissl
mkneissl

Reputation: 4912

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.

Upvotes: 3

Mitch Blevins
Mitch Blevins

Reputation: 13196

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

Upvotes: 5

Dirk
Dirk

Reputation: 31053

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] => ...
}

Upvotes: 2

Related Questions