Title: Use Guice multibindings with assisted inject for the set members
Tags: java;scala;guice
Question: I have a class ```PluginManager``` which accepts a ```Set<Plugin&gt;``` using the Guice multi-bindings feature. However, the ```PluginManager``` has some runtime information that needs to be passed to the ```Plugin``` constructor.

This seems to be a perfect use-case for Guice assisted injection i.e. my ```PluginManager``` would have ```Set<PluginFactory&gt;``` injected, where the runtime information is provided to each factory, resulting in the required ```Plugin``` instances.

I don't know the syntax to use in the ```Module``` however. The multibinder ```addBinding``` does not seem to have any facility to connect the result of ```FactoryModuleBuilder```.

I can create my own custom Factory implementations and multibind that obviously, but is there a way to combine multibinder with assisted inject?


Here is the accepted answer: I think this gives you an example to do exactly what you want. Please note that scala's multibinder has a pending pull request that allows you to create the set binder in multiple places. 

```object Test {
  trait Plugin {
    def name(): String
  }

  object Plugin {
    trait Factory[+T <: Plugin] {
      def newPlugin(name: String): T
    }
  }

  case class MyPlugin @Inject() (@Assisted name: String) extends Plugin
  case class OtherPlugin @Inject() (@Assisted name: String) extends Plugin

  class PluginManager @Inject() (pluginFactories: Set[Plugin.Factory[Plugin]]) {
    for (factory <- pluginFactories) {
      println(factory.newPlugin("assisted injection"))
    }
  }

  def main(args: Array[String]): Unit = {
    val injector = Guice.createInjector(new ScalaModule {
      override def configure(): Unit = {
        val plugins = ScalaMultibinder.newSetBinder[Plugin.Factory[Plugin]](binder)
        plugins.addBinding().to[Plugin.Factory[MyPlugin]]
        plugins.addBinding().to[Plugin.Factory[OtherPlugin]]

        bindFactory[Plugin, MyPlugin, Plugin.Factory[MyPlugin]]()
        bindFactory[Plugin, OtherPlugin, Plugin.Factory[OtherPlugin]]()

        bind[PluginManager].asEagerSingleton()
      }

      def bindFactory[I: Manifest, C <: I : Manifest, F: Manifest](): Unit = {
        import net.codingwell.scalaguice._
        install(new FactoryModuleBuilder()
          .implement(typeLiteral[I], typeLiteral[C])
          .build(typeLiteral[F]))
      }
    })
  }
}
```

You can do a bunch of things depending on the style you want. For example you could make a generic addPlugin method (when a newer version of scala-guice is released) like this:

```val injector = Guice.createInjector(new ScalaModule {
  override def configure(): Unit = {
    bindPlugin[MyPlugin]()
    bindPlugin[OtherPlugin]()

    bind[PluginManager].asEagerSingleton()
  }

  def bindPlugin[T <: Plugin : Manifest](): Unit = {
    val plugins = ScalaMultibinder.newSetBinder[Plugin.Factory[T]](binder)
    plugins.addBinding().to[Plugin.Factory[T]]
    bindFactory[Plugin, T, Plugin.Factory[T]]()
  }

  def bindFactory[I: Manifest, C <: I : Manifest, F: Manifest](): Unit = {
    import net.codingwell.scalaguice._
    install(new FactoryModuleBuilder()
      .implement(typeLiteral[I], typeLiteral[C])
      .build(typeLiteral[F]))
  }
})
```

Comment for this answer: I know it does! =) I wrote the pull request =).
Comment for this answer: Thank you, I was close to this but didn't have a generic type on my Factory trait, and so Guice was telling me I couldn't bind each plugin because it had already been bound. This worked perfectly!
Comment for this answer: BTW, I did run into the issue you mentioned with scala-guice and Multibinder (https://github.com/codingwell/scala-guice/issues/29) but the code in your referenced pull request fixed it. Thanks!


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2014:00:10/22/14', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<java><scala><guice>', 'Title': 'Use Guice multibindings with assisted inject for the set members', 'ViewCount': 1048, 'id': 26514009, 'user_AboutMe': 'Raman (<a href="https://www.linkedin.com/in/rocketraman" rel="nofollow noreferrer">LinkedIn</a>) has over 20 years of business and technology experience including business and functional analysis, systems design, development and implementation, and team leadership. Raman has worked as a Senior Consultant for Deloitte Consulting, application architect and development lead for a Fortune 100 financial institution, and as a technologist for various startups.</p>\nHe has extensive knowledge and experience with best practices in software design and development is an Apache committer, and has contributed patches to <a href="http://git-scm.com/" rel="nofollow noreferrer">Git</a>, <a href="http://akka.io/" rel="nofollow noreferrer">Akka</a>, <a href="http://spring.io" rel="nofollow noreferrer">Spring</a>, and other open source projects. His technical expertise includes system architecture, Java, Kotlin, and Scala development, database design and administration, UNIX system administration, devops (cloud and Docker), and security. In addition, Raman leverages Machine Learning techniques to deliver additional value beyond what can be achieved with traditional development.\nRaman has a Bachelor of Applied Science in <a href="http://www.systems.uwaterloo.ca/" rel="nofollow noreferrer">Systems Design Engineering</a> with an Option in Management Sciences from the University of Waterloo..</p>\n', 'user_AccountId': 190269.0, 'user_DisplayName': 'Raman', 'user_Reputation': 15770.0, 'user_Views': 1469.0, 'user_id': 430128.0}}