1

I have seen dependency injection written the following way when creating something like a Controller or Service layer in MVC Play apps (using javax.inject.Inject or com.google.inject.Inject):

class Controller @Inject()(thing: Something) { ... }

And I have also seen it written like this:

class Controller @Inject()(val thing: Something) { ... }

Is there any benefit to writing one over the other? What's the difference?

If I were to hazard a guess, I'd think that one instantiates a new instance of that parameter where the other just reuses the same instance of whichever parameter was passed in, but I wouldn't know which is which and I don't know whether that's even right or not.

James Whiteley
  • 3,363
  • 1
  • 19
  • 46
  • 1
    I don't think injection makes any difference here; see https://stackoverflow.com/questions/14694712/do-scala-constructor-parameters-default-to-private-val for actual effect of `val`. – Alexey Romanov Mar 29 '19 at 09:50
  • At work, I've seen people use a mixture of `val` and `[not-val]` seemingly like they know what they're doing, but I can never tell if there's an actual difference between the two or if they're just copying what people before them have done. It seems like there's a convention where I work of "use val on any config-related injection" and I always assumed that was just so the app wasn't creating a new instance of the config whenever it was injected... But then some people seem to completely flip that. – James Whiteley Mar 29 '19 at 10:00
  • 2
    Again, I'd be surprised if it has anything to do with injection, and if there is such a convention it may be based on misunderstanding. Search for usages of `val` parameters outside their class; if there are any, it has to be `val` (for case classes, `val` is implied). If there aren't, maybe there used to be, or they were expected, or as you say someone just copied it and didn't think about it. – Alexey Romanov Mar 29 '19 at 10:31

1 Answers1

3

It is not about injection, it is about the class properties.

class Controller @Inject()(thing: Something) { ... }

It declares the constructor parameter. You can use thing in the class body.

class Controller @Inject()(val thing: Something) { ... }

It creates the thing getter. So it can be used later as:

class Controller @Inject()(val thing: Something) { ... }
val c1 = new Controller('Something')
c1.thing \\ here is `Something`

Here is a good thread about this: Do scala constructor parameters default to private val?

Andriy Kuba
  • 8,093
  • 2
  • 29
  • 46