codingwell / scala-guice

Scala extensions for Google Guice
Apache License 2.0
341 stars 44 forks source link

Where did `@Inject` annotations go? #62

Closed ghost closed 7 years ago

ghost commented 7 years ago

I've used Guice for Java + Groovy projects for years now, and am used to property and/or constructor injection like so:

class Fizz {
    @Inject
    BillingService billingService

    // ...
}

class Buzz {
    @Inject
    Buzz(DataService dataService) {
        // ...
    }

    // ...
}

But in Scala constructors work a lot different:

class Fizz(val billingService : BillingService) {
    // ...
}

And in all of your code examples + docs I don't see @Inject used anywhere. So I ask: does @Inject still exist in scala-guice, or has it been replaced by something else? If it doesn't exist, then how does Guice know which fields to inject and which ones not to?

tsuckow commented 7 years ago

I think you are looking for class fizz @Inject()(val billing...)

ghost commented 7 years ago

Hmmm thanks! Ok so it looks like that with this library, the @inject annotation always goes as the class-level (not constructor or field level like with Java/Groovy)?

And I'm guessing that means that this library doesn't support "partial" injections: that is, you have to let Guice inject all fields included in the Scala primary constructor? Thanks again!

tsuckow commented 7 years ago

You can annotate members and the syntax I posted is for constructors. I'd post some better examples but I haven't honestly been doing that much Scala work lately and I am replying from my phone.

I'd look up annotating methods and constructors in Scala. This library simply relies on the annotations from guice itself.

Here is an example I found, there are probably much better ones: http://michaelpnash.github.io/guice-up-your-scala/

ghost commented 7 years ago

Thanks again @tsuckow so I read that article (Guice Up Your Scala) and admit its a great read. There's only one passage in there that troubles me. Under the section titled "The Good, The Bad & The Ugly", the author states (for the Bad):

"(The Bad) I have to annotate my classes with Guice-specific annotations, although there is a JSR on the way to standardize these, which makes it a bit less objectionable. What happens if I need to inject to a class I don’t have source for (e.g. something in an existing Java library that I’m calling?"

Does this mean that I can't use scala-guice for injecting my classes with third party (open source) library classes?!? If not, what's the author saying there?

Thanks again!

tsuckow commented 7 years ago

I believe he is saying that if you have: Your own class Fizz that uses Inject to inject Foo Foo is a third party library that depends on Bar being passed to the constructor Then you cannot simply use Inject to make Foo get Bar because you can't add the annotation to the Foo constructor. You would have to bind to an instance of Foo that you created and passed Bar or you would have to make a Foo provider that would do it.

I don't think it stops you from using guice in any way.

scala-guice is a fairly light wrapper on guice that mostly reduces some boiler plate. You might have better luck asking some of these questions on the guice mailing list. https://groups.google.com/forum/m/#!forum/google-guice

ghost commented 7 years ago

👍 thanks @tsuckow