I want to upgrade to Play 2.6, and have some questions about dependency injection (DI). I'm new to DI.Are there any benefits with using Guice DI, instead of Scala compile time DI?Are things one can do, with Guice, that cannot be done using the compile-time approach?
(With Scala compile time DI, I suppose I mean this: https://github.com/playframework/play-scala-compile-di-example.I'm fine with passing "many" constructor arguments and wiring things myself; I don't consider not-having-to-write such code a major benefit.)
What about performance: Are there any differences between the compile-time and Guice-runtime approaches?For app server startup time?And later, when the app has been running for a while already — are the compile-time and Guice-runtime approaches then equally fast?
Which alternative (Guice-runtime-DI or compile-time-DI) do you think offers the lowest risk that Play Framework will deprecate it and replace it with something else, in the future? (forcing me to relearn and rewrite/update my Play related stuff)... I'm thinking that Guice might be a bit higher risk? Because it's been broken out from core recently. And, there are alternatives to Guice, like Spring, MacWire, ... and Dagger 2 — Dagger 2 seems to be more popular than Guice nowadays (newer, but still has a lot more GitHub stars). So perhaps in the future, the default recommended DI will change from Guice to something else? (since there's other more popular stuff out there already)... But there are no "competing" implementations of compile-time DI? So perhaps the compile-time method is more "stable", then?
What about Scala Native, https://github.com/scala-native/scala-native — I suppose Scala Native won't work with Guice and runtime-DI? But compile-time-DI works fine with Scala Native, right?
Hi,I want to upgrade to Play 2.6, and have some questions about dependency injection (DI). I'm new to DI.Are there any benefits with using Guice DI, instead of Scala compile time DI?Are things one can do, with Guice, that cannot be done using the compile-time approach?
(With Scala compile time DI, I suppose I mean this: https://github.com/playframework/play-scala-compile-di-example.I'm fine with passing "many" constructor arguments and wiring things myself; I don't consider not-having-to-write such code a major benefit.)
What about performance: Are there any differences between the compile-time and Guice-runtime approaches?For app server startup time?And later, when the app has been running for a while already — are the compile-time and Guice-runtime approaches then equally fast?
Which alternative (Guice-runtime-DI or compile-time-DI) do you think offers the lowest risk that Play Framework will deprecate it and replace it with something else, in the future? (forcing me to relearn and rewrite/update my Play related stuff)
... I'm thinking that Guice might be a bit higher risk? Because it's been broken out from core recently. And, there are alternatives to Guice, like Spring, MacWire, ... and Dagger 2 — Dagger 2 seems to be more popular than Guice nowadays (newer, but still has a lot more GitHub stars). So perhaps in the future, the default recommended DI will change from Guice to something else? (since there's other more popular stuff out there already)
... But there are no "competing" implementations of compile-time DI? So perhaps the compile-time method is more "stable", then?
What about Scala Native, https://github.com/scala-native/scala-native — I suppose Scala Native won't work with Guice and runtime-DI? But compile-time-DI works fine with Scala Native, right?
--Thanks & regards,KajMagnus
You received this message because you are subscribed to the Google Groups "Play Framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/e40c8021-207a-4585-b28c-48265f5fc011%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Thanks & regards,KajMagnus
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/e40c8021-207a-4585-b28c-48265f5fc011%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
> instantiate all your singletons in production mode, while doing so lazily in dev mode; that's hard to do with plain Scala codeReally? I'm getting ready to migrate to compile-time DI and thought this would not be particularly hard to do. I am using quite a few singletons there.
So for the time being, should I stick to runtime or compile-time DI?
I'm finding that in my app [https://github.com/ScalaWilliam/ActionFPS] runtime DI is a bit fragile, though it could be just me misusing it.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framework+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/play-framework/181bac95-56c5-483e-882b-ef205c3fe956%40googlegroups.com.
A few personal opinions. I know Guice moderately well, but my own Play application (which long predates the introduction of Guice to Play) uses its own homebrew DI solution, named Ecology.(More precisely, it eschews DI per se in favor of a more old-fashioned runtime-dependencies model that uses a more explicit "god object". I've been using essentially this same approach in five different languages over the past 18 years: it's not fancy, but works consistently and well. The point is, there are *many* options for managing your dependencies in Play.)
On Tue, Jul 18, 2017 at 6:35 AM, Kaj Magnus Lindberg <kajma...@gmail.com> wrote:I want to upgrade to Play 2.6, and have some questions about dependency injection (DI). I'm new to DI.Are there any benefits with using Guice DI, instead of Scala compile time DI?Are things one can do, with Guice, that cannot be done using the compile-time approach?Probably not? They're both approaches for decomposing your application into decoupled pieces, and wiring those pieces together so they can access each other.The only thing that's a bit easier with runtime dependency, in my experience, is managing initialization order. I don't know offhand how Play's example compile-time DI deals with mutual dependencies, which tends to get many naive DI solutions into trouble as they try to scale up. (Guice handles this with the "Provider" mechanism.) Whether this is an issue or not depends on how you code -- in principle, it's a non-issue for truly functional code, but I've never managed to get a *complex* application to production without initialization order becoming an issue somewhere along the line.
(With Scala compile time DI, I suppose I mean this: https://github.com/playframework/play-scala-compile-di-example.I'm fine with passing "many" constructor arguments and wiring things myself; I don't consider not-having-to-write such code a major benefit.)That's fair, and a reasonable decision. Just keep in mind that dependencies tend to grow -- at this point, my server has ~70 components (just the ones *I* have added, separate from the ones built into Play), with each one depending on an average of ~10 others, and the number is still rising fairly rapidly. You should think about the overall complexity of your problem, and how many inter-related subsystems you are likely to need in the long run.
What about performance: Are there any differences between the compile-time and Guice-runtime approaches?For app server startup time?And later, when the app has been running for a while already — are the compile-time and Guice-runtime approaches then equally fast?I suspect you'd have to benchmark to get any real answers here, but my suspicion is that any difference between the two is basically noise.Which alternative (Guice-runtime-DI or compile-time-DI) do you think offers the lowest risk that Play Framework will deprecate it and replace it with something else, in the future? (forcing me to relearn and rewrite/update my Play related stuff)... I'm thinking that Guice might be a bit higher risk? Because it's been broken out from core recently. And, there are alternatives to Guice, like Spring, MacWire, ... and Dagger 2 — Dagger 2 seems to be more popular than Guice nowadays (newer, but still has a lot more GitHub stars). So perhaps in the future, the default recommended DI will change from Guice to something else? (since there's other more popular stuff out there already)... But there are no "competing" implementations of compile-time DI? So perhaps the compile-time method is more "stable", then?No -- I'd say almost the opposite, frankly. There are many runtime-DI systems because it's an old and well-worn concept that has had lots of time to mature, much of that in the Java ecosystem.By contrast, I've been seeing a lot of discussion in the FP communities about how best to deal with dependency management, and I haven't gotten the sense that there is anything resembling a best-practice consensus yet. (Although personally, I think the Eff approach sounds quite promising -- it's the first statically-typed approach that I've seriously considered adopting, that appears to deal with the real-world complexities well.)I have no insight into what the Play team might do about changing their default recommendations in the future. But Guice is by now relatively old, complete, mature and stable, and is what I usually use when coding for clients, on the grounds that it appears to be the safest option going forward. Changing the default would probably be an considerable hassle for the Play team, so I doubt they would do so casually. In my experience, the team is very conscious of compatibility breakages, and does so relatively slowly and carefully.I suspect that compile-time DI will prove to be the *best* option in the long run, but I think folks are still figuring out the best answers there. There are many different ways you could construct your application with statically-typed components; the Play docs are just giving one straightforward option as an example. Having not used Play's current recommended approach, I can't speak to it with any confidence; I am curious how well it works when you get to large numbers of inter-dependent application components.
What about Scala Native, https://github.com/scala-native/scala-native — I suppose Scala Native won't work with Guice and runtime-DI? But compile-time-DI works fine with Scala Native, right?Almost certainly correct, at least that Guice per se (or anything else dependent on reflection) won't work. Some forms of runtime-dependency-management would work just fine, so long as they aren't reflection-based -- for example, my above-linked Ecology system is already in heavy use on both the JVM and JS platforms, and will probably work fine on Native.But I don't know if Scala Native is ever likely to run Play, so I'm not sure how relevant that is...
On Tue, Jul 18, 2017 at 3:35 AM, Kaj Magnus Lindberg <kajma...@gmail.com> wrote
Which alternative (Guice-runtime-DI or compile-time-DI) do you think offers the lowest risk that Play Framework will deprecate it and replace it with something else, in the future? (forcing me to relearn and rewrite/update my Play related stuff)... I'm thinking that Guice might be a bit higher risk? Because it's been broken out from core recently. And, there are alternatives to Guice, like Spring, MacWire, ... and Dagger 2 — Dagger 2 seems to be more popular than Guice nowadays (newer, but still has a lot more GitHub stars). So perhaps in the future, the default recommended DI will change from Guice to something else? (since there's other more popular stuff out there already)What exactly are you worried about? If you're concerned about Play removing the play-guice module, I don't think that is likely. Even if it were removed, you'd still be able to wire the components together manually. The Guice module is just wiring together components provided by Play. The reason there is no core dependency is there doesn't need to be. There's no reason for other DI users to have the extra dependency if they don't need it.Dagger 2 is meant for Java, and Play also supports that: https://github.com/playframework/play-java-dagger2-example
... But there are no "competing" implementations of compile-time DI? So perhaps the compile-time method is more "stable", then?There are competing strategies for compile-time DI as well. There's the cake pattern, the thin cake pattern (what Play promotes), Scala implicits, the Reader monad, etc. All these things are possible to integrate with Play's approach. I don't think it's fair to say that compile-time DI in Scala is settled.Looking at it in terms of how you design your components, the approaches that promote using constructor injection are probably the most "stable" and the most interchangeable. It should be relatively trivial to migrate a Guice app using constructor injection to the thin cake pattern or vice versa, since your components should look exactly the same. Your integration tests (anything using GuiceApplicationBuilder or the injector) would probably need to change though.
On Tuesday, July 18, 2017 at 4:06:15 PM UTC+2, Justin du coeur wrote:A few personal opinions. I know Guice moderately well, but my own Play application (which long predates the introduction of Guice to Play) uses its own homebrew DI solution, named Ecology.(More precisely, it eschews DI per se in favor of a more old-fashioned runtime-dependencies model that uses a more explicit "god object". I've been using essentially this same approach in five different languages over the past 18 years: it's not fancy, but works consistently and well. The point is, there are *many* options for managing your dependencies in Play.)I had a look at Ecology. I'm not good enough at Scala to understand the implementation :- PInteresting to know that one can write one's own DI lib though and that it's not that super much code :- )
Ok yes I've run into some bugs related to init order, in my app, already, and have had to spend some time debugging. (Mostly forward-referencing non-lazy vals that were still 'null'.)
I'll probably use constructos, and pass lots of objs and things to the constructors. Even if it's a bit verbose, at least I won't have to learn anything new, which I would forget after a year, and have to re-learn again and again :- P
What about Scala Native, https://github.com/scala-native/scala-native — I suppose Scala Native won't work with Guice and runtime-DI? But compile-time-DI works fine with Scala Native, right?Almost certainly correct, at least that Guice per se (or anything else dependent on reflection) won't work. Some forms of runtime-dependency-management would work just fine, so long as they aren't reflection-based -- for example, my above-linked Ecology system is already in heavy use on both the JVM and JS platforms, and will probably work fine on Native.But I don't know if Scala Native is ever likely to run Play, so I'm not sure how relevant that is...Ok. I was thinking / hoping that maybe maybe after 10 years or so.