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] 
> <javascript:>> 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] <javascript:>.
>> To post to this group, send email to [email protected] 
>> <javascript:>.
>> 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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to