This sounds, possibly, like a good use case for a child injector. I can't seem to find the wiki article on them, but I saw some stackoverflow URLs pop up and the API has a decent javadoc:
See: http://google.github.io/guice/api-docs/latest/javadoc/com/google/inject/Injector.html#createChildInjector-java.lang.Iterable- On Mon, Jul 6, 2015 at 2:21 PM Ryan Leach <[email protected]> wrote: > Thankyou for the concern about the anti-pattern but in the API there are > producers that create objects from factories that I'm going to add soon, > maybe as a submodule that will require the instances. > > If I could use the parent projects injector for the other classes I would, > but since I can't (it only injects into the main application class) I'm > using this as a workaround and recreating the injector. Ideally I would be > able to get the parent project to inject the sub-classes but it isn't > exposed. > > I ended up solving the problem by changing the module to a variable in the > ServiceInjector that gets set from the main application when it receives a > construction event, before the injector is used then made the injector lazy. > > I'm not sure I like this solution but it works for now. > > @Plugin(id = "au.id.rleach.overmind", name = "Overmind", version = > "0.0.1-SNAPSHOT") > final class OvermindPlugin { > > @Inject > private val game: Game = null > @Inject > private val logger: Logger = null > @Inject > private val pluginManager: PluginManager = null > @Inject > private val serviceManager: ServiceManager = null > @Inject > private val eventManager: EventManager = null > @Inject > private val gameRegistry: GameRegistry = null > @Inject > private val teleportHelper: TeleportHelper = null > > > > @Subscribe def onConstruction(event: ConstructionEvent): Unit = { > logger debug "Plugin constructed" > ServiceInjector.module = new OModule(this, game, logger, pluginManager, > serviceManager, eventManager, gameRegistry, teleportHelper) > val x = new TestListener with Listener with ServiceInjector > x.init() > } > > } > > > > > > class OModule(val plugin: Object, val game: Game, val logger: Logger, val > pluginManager: PluginManager, val serviceManager: ServiceManager, val > eventManager: EventManager, val gameRegistry: GameRegistry, val > teleportHelper: TeleportHelper) extends Module { > > > > override def configure(binder: Binder): Unit = { > binder.bind(classOf[Game]).toInstance(game) > binder.bind(classOf[Logger]).toInstance(logger) > binder.bind(classOf[PluginManager]).toInstance(pluginManager) > binder.bind(classOf[ServiceManager]).toInstance(serviceManager) > binder.bind(classOf[EventManager]).toInstance(eventManager) > binder.bind(classOf[GameRegistry]).toInstance(gameRegistry) > binder.bind(classOf[TeleportHelper]).toInstance(teleportHelper) > > binder.bind(classOf[Object]).toInstance(plugin) > > binder.bind(classOf[Object]).annotatedWith(Names.named(plugin.getClass.getAnnotation(classOf[Plugin]).id())).toInstance(plugin); > //bind(classOf[File]).annotatedWith(new > ConfigDirAnnotation(true)).toInstance(Loader.instance.getConfigDir) > } > } > > /** > * Marker class to mark that the class will not function correctly unless > initialized after injection/construction. > */ > trait Initializable { > /** > * Must be run after a class is injected to get the class ready to use > */ > def init() : Unit > > > } > > > trait ServiceInjector { > ServiceInjector.inject(this) > } > > object ServiceInjector { > > var module : Module = null > > private lazy val injector = Guice.createInjector( > module > ) > > def inject(obj: Initializable) = { > injector.injectMembers(obj) > obj.init() > > > } > > def inject(obj: AnyRef) = { > injector.injectMembers(obj) > } > } > > > On Monday, July 6, 2015 at 9:01:30 PM UTC+9:30, Nate Bauernfeind wrote: > >> In general this is an anti-pattern in Guice. If you have to pass >> instances of every object in your graph to the guice module constructors >> then you're not using Guice for any injection at all. What does your java >> version of this use-case look like? It seems that you did not translate it >> to Scala correctly. >> >> Guice works in Scala just like it works in Java. There is a wonderful >> project which introduces the right amount of syntactic sugar to make your >> life easier in Scala, but fundamentally it's all the same. >> >> Take a look at this project and let me know if you still have Scala >> specific questions: >> https://github.com/codingwell/scala-guice >> >> Thanks, >> Nate >> >> On Mon, Jul 6, 2015 at 3:56 AM Ryan Leach <[email protected]> wrote: >> > First up sorry to reply to such an old post, but it appears pretty high in >>> search when I look for the problem, so figured anyone else finding it would >>> appreciate an answer if they found the same post. >>> >>> I'm very new to Scala and trying to work out how I can use the previous >>> pattern for dependency injection, when the Guice Module itself needs >>> references to instances passed in from elsewhere. >>> >>> But since traits can't have constructors, and neither can the Companion >>> Object it looks like I'm screwed? >>> >>> package au.id.rleach.overmind.guice >>> >>> import com.google.inject.{Provides, Guice, Binder, Module} >>> import org.slf4j.Logger >>> import org.spongepowered.api.service.ServiceManager >>> import org.spongepowered.api.world.TeleportHelper >>> import org.spongepowered.api.{GameRegistry, Game} >>> import org.spongepowered.api.plugin.PluginManager >>> import org.spongepowered.api.scoreboard.ScoreboardBuilder >>> import org.spongepowered.api.service.event.EventManager >>> >>> class OModule(val game: Game, val logger: Logger, val pluginManager: >>> PluginManager, val serviceManager: ServiceManager, val eventManager: >>> EventManager, val gameRegistry: GameRegistry, val teleportHelper: >>> TeleportHelper) extends Module { >>> >>> override def configure(binder: Binder): Unit = { >>> binder.bind(classOf[Game]).toInstance(game) >>> binder.bind(classOf[Logger]).toInstance(logger) >>> binder.bind(classOf[PluginManager]).toInstance(pluginManager) >>> binder.bind(classOf[ServiceManager]).toInstance(serviceManager) >>> binder.bind(classOf[EventManager]).toInstance(eventManager) >>> binder.bind(classOf[GameRegistry]).toInstance(gameRegistry) >>> binder.bind(classOf[TeleportHelper]).toInstance(teleportHelper) >>> //bind(classOf[File]).annotatedWith(new >>> ConfigDirAnnotation(true)).toInstance(Loader.instance.getConfigDir) >>> } >>> } >>> >>> trait ServiceInjector { >>> ServiceInjector.inject(this) >>> } >>> >>> object ServiceInjector { >>> private val injector = Guice.createInjector( >>> //#### >>> new OModule()//compilation error. >>> //#### >>> ) >>> def inject(obj: AnyRef) = injector.injectMembers(obj) >>> } >>> >>> I realize that the object is being initialized when the class is loaded, >>> and that is before I even have a copy of the instance to pass to OModule, >>> so it seems the whole advice is flawed? >>> >>> On Monday, December 22, 2008 at 9:57:41 PM UTC+10:30, Jan Kriesten wrote: >>>> >>>> >>>> > Can you give me a demo that about integrate scala into guice? >>>> >>>> Well, it's actually almost as referred to you in the link from the >>>> other answer: >>>> >>>> >>>> http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di/ >>>> >>>> class MyClient { >>>> @Inject val toBeInjected: AnotherClass = toBeInjected // !! >>>> } >>>> >>>> trait ServiceInjector { >>>> ServiceInjector.inject( this ) >>>> } >>>> >>>> object ServiceInjector { >>>> private val injector = Guice.createInjector( Array[Module]( new >>>> YourModule ) ) >>>> def inject( obj: AnyRef ) = injector.injectMembers( obj ) >>>> } >>>> >>>> Usage: >>>> >>>> val client = new MyClient with ServiceInjector >>>> >>>> or: >>>> >>>> class InjectedMyClient extends MyClient with ServiceInjector >>>> >>>> Best regards, --- Jan. >>>> >>>> >>>> -- >>> You received this message because you are subscribed to the Google >>> Groups "google-guice" group. >>> >> To unsubscribe from this group and stop receiving emails from it, send an >>> email to [email protected]. >>> To post to this group, send email to [email protected]. >> >> >>> Visit this group at http://groups.google.com/group/google-guice. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/google-guice/0b5c01b0-ad63-4a37-916e-6b00c7ceaa8c%40googlegroups.com >>> <https://groups.google.com/d/msgid/google-guice/0b5c01b0-ad63-4a37-916e-6b00c7ceaa8c%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> For more options, visit https://groups.google.com/d/optout. >>> >> -- > You received this message because you are subscribed to the Google Groups > "google-guice" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/google-guice. > To view this discussion on the web visit > https://groups.google.com/d/msgid/google-guice/5009b55d-52cf-4ba8-ba4f-34fe23f9590d%40googlegroups.com > <https://groups.google.com/d/msgid/google-guice/5009b55d-52cf-4ba8-ba4f-34fe23f9590d%40googlegroups.com?utm_medium=email&utm_source=footer> > . > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "google-guice" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/google-guice. To view this discussion on the web visit https://groups.google.com/d/msgid/google-guice/CAHNex9-xLA4j%2B4GL361F-8zqWM-MtNvvS-jzNfxxVcs38hBTng%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
