将Guice多重绑定与辅助注入一起用于集合成员 [英] Use Guice multibindings with assisted inject for the set members

查看:71
本文介绍了将Guice多重绑定与辅助注入一起用于集合成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 PluginManager 类,它使用Guice多重绑定功能接受 Set< Plugin> .但是, PluginManager 具有一些运行时信息,需要将这些信息传递给 Plugin 构造函数.

I have a class PluginManager which accepts a Set<Plugin> using the Guice multi-bindings feature. However, the PluginManager has some runtime information that needs to be passed to the Plugin constructor.

这似乎是Guice辅助注入的完美用例,即我的 PluginManager 将注入 Set< PluginFactory> ,其中将运行时信息提供给每个工厂,从而产生必需的 Plugin 实例.

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

但是我不知道在 Module 中使用的语法.多绑定器 addBinding 似乎没有任何功能可以连接 FactoryModuleBuilder 的结果.

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.

我可以创建自己的自定义Factory实现并进行显然的多重绑定,但是有没有办法将multibinder与辅助注入结合起来?

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

推荐答案

我认为这为您提供了一个示例,可以准确地完成您想要的事情.请注意,scala的multibinder具有悬而未决的拉取请求,可让您在多个位置创建设置的活页夹.

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]))
      }
    })
  }
}

您可以根据自己想要的样式来做很多事情.例如,您可以制作一个通用的addPlugin方法(当发布新版本的scala-guice时),如下所示:

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]))
  }
})

这篇关于将Guice多重绑定与辅助注入一起用于集合成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆