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.

Reply via email to