【问题标题】:How to bind one implementation to a few interfaces with Google Guice?如何使用 Google Guice 将一个实现绑定到几个接口?
【发布时间】:2011-01-25 09:43:24
【问题描述】:

我需要绑定一个类作为两个接口的实现。它应该绑定在一个单例范围内。

我做了什么:

bind(FirstSettings.class).
    to(DefaultSettings.class).
    in(Singleton.class);
bind(SecondSettings.class).
    to(DefaultSettings.class).
    in(Singleton.class);

但是,很明显,这会导致创建两个不同的实例,因为它们绑定到不同的键。

我的问题是我该怎么做?

【问题讨论】:

    标签: java dependency-injection guice


    【解决方案1】:

    Guice 的 wiki 有 a documentation about this use case

    基本上,这是你应该做的:

    // Declare that the provider of DefaultSettings is a singleton
    bind(DefaultSettings.class).in(Singleton.class);
    
    // Bind the providers of the interfaces FirstSettings and SecondSettings
    // to the provider of DefaultSettings (which is a singleton as defined above)
    bind(FirstSettings.class).to(DefaultSettings.class);
    bind(SecondSettings.class).to(DefaultSettings.class);
    

    无需指定任何额外的类:只需根据Providers 进行思考,答案就很自然了。

    【讨论】:

      【解决方案2】:

      我找到的解决方案是:

      bind(FirstSettings.class).
          to(DefaultSettings.class).
          in(Singleton.class);
      bind(SecondSettings.class).
          to(FirstSettings.class).
          in(Singleton.class);
      

      它适用于我的情况,因为 SecondSettings 扩展了 FirstSettings。

      【讨论】:

      • 仅当 SecondSettings 是 FirstSettings 的子类、子接口时才有效。对于这种情况以及在 FirstSettings 和 SecondSettings 之间不存在链接的其他情况,有一些解决方案。
      【解决方案3】:

      所以,DefaultSettingsFirstSettingsSecondSettings 的实现,即:

      public class DefaultSettings implements FirstSettings, SecondSettings
      {
      }
      

      假设你有一个班级EngineAEngineB

      public class EngineA
      {
          @Inject
          private FirstSettings settings;
      }
      
      public class EngineB
      {
          @Inject
          private SecondSettings settings;
      }
      

      并且您想注入相同的实现。

      你可以声明一个接口DefaultSettingsInterface

      public interface DefaultSettingsInterface extends FirstSettings, SecondSettings
      {
      }
      

      并使DefaultSettings 实现DefaultSettingsInterface

      public class DefaultSettings implements DefaultSettingsInterface
      {
      }
      

      那么配置可能是:

      bind(FirstSettings.class).to(DefaultSettingsInterface.class);
      bind(SecondSettings.class).to(DefaultSettingInterface.class);
      bind(DefaultSettingsInterface.class).to(DefaultSettings.class).in(Singleton.class);
      

      【讨论】:

      • 谢谢,鲍里斯!我相信您的解决方案有效!我自己刚刚找到了另一种方法:bind(FirstSettings.class)。到(默认设置.class)。在(单例类);绑定(SecondSettings.class)。到(FirstSettings.class)。在(单例类);它似乎也有效。你怎么看?
      • 我不知道 FirstSettings 扩展了 SecondSettings。在这种情况下,它是有效的并且更短。将您的解决方案发布为答案,并在一段时间后将其推广为最佳解决方案:)
      • 是的,这是真的。我的错,我没有提到:)
      • Pavel,您的解决方案只有在您拥有 FirstSettings 扩展/实施 SecondSettings 时才有效。此外,这个解决方案看起来像样板文件,其中 guice 提供了简单而优雅的解决方案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多