简体   繁体   中英

How does one use Google Guice's @Inject with Scala / (Play 2.4.x)

I'm ready to drink the koolaid :)

Play is moving to Google Guice ( https://github.com/google/guice ) so I guess I've got no real choice here but to tag along for the ride.

Somehow I'm missing something however.

I get the "don't call us we'll call you" mentality and the core reason for a Dependency Injection solution - less brittle and more testable code.

Sometimes however all I want is just a simple toothpick and don't feel the need to bake a cake, or worse yet write the complete recipe for baking one, just to get one...

Scala, the language seems to have made toothpick factories trivial (One of Guice's arguments is the cost of building factories (in Java) -- so to me that argument is off the table at least but that does't negate the rest of the DI issues I know).

In scala you have a Companion object (sorry having a Serenity flashback -- I need a moment - ok good to go -- oh and blame Odersky for that combination of words not me please...).

For the Toothpick class:

case class Toothpick(color: Color) 

object Toothpick {
  def redPlease = {
    Toothpick(Color.RED) 
  }
}

Of course you can get fancy with the apply and a host of other scala niceties to get the exact Toothpick you want merely by referring the Toothpick "object":

val myShinyRedToothpick = Toothpick.redPlease

So in this case Toothpick the object is an instant factory.

Making something easy does not make it right -- it just makes it easy.

The overview of Google's Guice seems to be: One Factory to Rule Them All .

Ok - I can live with that. They got their first -- they own all the land -- we'll be sharecroppers forever. Game over.

What I need is the toothpick example of how to USE a Guice'd up factory. How do I get my freaking toothpick from within NORMAL Scala code please?

(Like I said I could be completely missing the point... so the feel free to hurl whatever monkey crap is needed to get me to look in the right direction if that is the case).

PS: I do not need a lesson in WHY - I merely want one in HOW .

So hey, here is a complicated HOW-TO. (Beware: Untested and thoroughly stupid code)

public class MyComplicatedGuiceModule extends AbstractModule {
  protected void configure() {
    // does some configuration stuff
  }

  @Provides
  @Named("RedToothPick")
  ToothPick provideRedToothPick() {
    ToothPick(Color.RED)
  }

  @Provides
  @Named("WhiteToothPick")
  ToothPick provideWithToothPick() {
    ToothPick(Color.WHITE)
  }
}

And to use this in your class, you would do something like this:

public class WildCleanToothService(@Named("RedToothPick") toothPick: ToothPick) {
}

Now, it is fair to argue: Why the complication? See how less lines the Scala code uses?

For me, the biggest benefits have been in testing the actual code. It boils down to: How do you test your companion object? What if it invoked some random service. How would we mock the service? Being able to plug-in dependencies makes it possible to test them individually and easily.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM