Java 在Guice中为特定客户机提供特定依赖项

Java 在Guice中为特定客户机提供特定依赖项,java,guice,Java,Guice,我试图绑定同一接口的两个特定实现。一个是常规服务,应该普遍使用,另一个是第一个服务的变体,它添加了缓存。后者必须只提供给几个类,而不是通常使用的类 我知道Guice中的所有绑定,包括命名绑定和注释绑定,但没有一个真正适合我的场景。我不希望我的客户机必须使用特定的注释或字符串值。它知道的越少越好。向其提供哪种依赖关系的决定必须来自外部,即来自模块 因此,如果命名绑定和注释绑定都没有了,我就只能绑定到一个具体实例。这是一个解决方案,因为它允许我在客户机的构造函数中提供特定的依赖关系,但我仍然觉得它不

我试图绑定同一接口的两个特定实现。一个是常规服务,应该普遍使用,另一个是第一个服务的变体,它添加了缓存。后者必须只提供给几个类,而不是通常使用的类

我知道Guice中的所有绑定,包括命名绑定和注释绑定,但没有一个真正适合我的场景。我不希望我的客户机必须使用特定的注释或字符串值。它知道的越少越好。向其提供哪种依赖关系的决定必须来自外部,即来自模块

因此,如果命名绑定和注释绑定都没有了,我就只能绑定到一个具体实例。这是一个解决方案,因为它允许我在客户机的构造函数中提供特定的依赖关系,但我仍然觉得它不太理想


你建议我做什么

除了私有模块绑定不能与注入器中的全局绑定冲突之外,您的问题与所需的问题非常相似。表达“此绑定适用于除此其他私有模块之外的任何地方”是很困难的

当您的构造函数不能被注释以单独表示DEP时,一种方法是手动创建类(即包装构造函数)。这意味着您的包装器将需要在构造函数更改时进行更改,但这可能不是什么大问题

public class CachingModule extends AbstractModule {
  @Override public void configure() {}

  // You could also write and bind a full Provider<T>, but this is more concise.
  @Provides FirstClassThatNeedsCaching provideFirst(
      CachingService service, Dep2 dep2) {
    return new FirstClassThatNeedsCaching(service, dep2);
  }

  @Provides SecondInterface provideSecond(CachingService service, Dep3 dep3) {
    return new SecondClassThatNeedsCaching(service, dep3);
  }
}
公共类CachingModule扩展了AbstractModule{
@重写公共void configure(){}
//您也可以编写和绑定完整的提供者,但这更简洁。
@提供所需的FirstClass设置(
开玩笑服务,第二部门(第二部门){
返回需要清理的新头等舱(服务,dep2);
}
@提供第二个接口提供第二个(CachingService服务,Dep3 Dep3){
返回需要更新的第二类(服务,部门3);
}
}

如果您想将要使用的
依赖项
的知识从
服务
中分离出来,那么我认为最好的做法是使用自定义
服务提供者实现提供者
类型,该类型显式地传递依赖项,正如你所建议的。这意味着我的服务需要知道它需要某种提供商,对吗?我想让它变得简单,就像知道依赖项的接口一样,没有什么更不清楚的了,为什么对需要缓存的少数类使用绑定注释是有问题的。为什么你不想让阅读需要缓存FooFactory的代码的人知道FooFactory在缓存呢?@NamshubWriter很简单。为什么我的客户机类甚至必须知道另一个组件正在缓存数据?这就是使用国际奥委会的首要意义。将组合从单个组件的关注点中去掉,以便您可以以任何可能的方式混合和匹配它们。如果我的组件碰巧知道会发生什么,即使它不是一个直接依赖项,这也会让使用它的每个人一遍又一遍地思考同一个解决方案。这是不可能的。IoC的要点是客户不需要找到依赖关系(“不要打电话给我们,我们会打电话给你”)。客户可能有很多理由想要确认注入的内容。让我用另一种方式问这个问题:为什么有些类需要获取一个未缓存的实例?