2013-05-01 71 views
11

我想要进行一系列处理元素并通过Guice将它们连接在一起。让我们假设以下路径:Guice辅助注入深入依赖层次结构

  • interface A通过class AImpl实施需要一定的输入
  • interface B通过class BImpl需求A
  • interface C通过class CImpl需求B
  • interface D通过class DImpl需求C
实施实施实施

A的依赖关系只能在运行时解析,而不能在配置时解析。通常的方法是使用辅助注塑在这种情况下,建立一个工厂,这需要缺少的实例作为参数,就像这样:

public interface AFactory { 
    public A createA(String input); 
} 

但我真正想要的是这样的:

public interface DFactory { 
    public D createD(String inputForA); 
} 

我不想在整个层次结构中手动传递AImpl特定的依赖关系。 Guice可以做到这一点吗?如果不是,那么优雅地避开这个问题的最好方法是什么,同时还能保留注射的好处?

回答

7

作弊方式:粘贴input中的一个静态变量或单身ThreadLocal。在管道启动之前将其设置,并在结束后将其清除。通过DI绑定其他所有内容。

花式的方式:A,请参阅@PipelineInput String inputString,但不要绑定它在主注射器。否则,像平常一样绑定依赖关系,包括在其他与管道相关的类中引用@PipelineInput。当你需要D时,从你的DFactory的实现中获得它,我打电话给PipelineRunner

public class PipelineRunner { 
    @Inject Injector injector; // rarely a good idea, but necessary here 

    public D createD(final String inputForA) { 
    Module module = new AbstractModule() { 
     @Override public void configure() { 
     bindConstant(inputForA).annotatedWith(PipelineInput.class); 
     } 
    }; 
    return injector.createChildInjector(new PipelineModule(), module) 
     .getInstance(D.class); 
    } 
} 

当然,结合尝试为ABCD将失败的PipelineRunner之外缺乏@PipelineInput String的--you'll得到CreationException当您创建与那些不满意的依赖注入器,因为你发现 - 但这些基于管道的依赖关系应该很容易分离成一个模块,并将其安装到子注入器中。

如果这感觉太哈克,记得PrivateModules也是“implemented using parent injectors”,而依赖注入的整点是让喜欢处于分离的方式提供给整个对象图inputForA的依赖。

+0

我记得我的同意,怎么一回事,因为这种“注入尝试为A,B ,C和d将失败PipelineRunner之外缺乏一个@PipelineInput字符串”这不行的,因为吉斯在配置时验证喷油器,一旦检测到有不满意的结合失败,这就是为什么你不能创建一个几乎完整的注射器,将由其子女完成。专用模块通过使用专用绑定器来克服这一点。 – orsg 2013-05-02 23:23:15

+0

我的错误;您必须将A,B,C和D与常数相邻。尽管如此,微不足道的修复。答案已更新。 – 2013-05-03 00:06:18

+1

好了,所以我必须是绑定的有关该管道的专用注射器孩子和家长注射器只知道工厂(“PipelineRunner”)内的一切。 – orsg 2013-05-03 12:48:49

1

我看到三个选项。它们取决于您更改的频率。

1)将input绑定为模块中的常量。如果您在创建Injector之前知道该值,并且永远不想更改该值,则此操作仅适用。见bindConstant

2)使用结合任一Ainput该模块内部的值的私人子模块。基本上你可以有两个或三个不同值的实例图。见newPrivateBinder

3)使用Scope阿拉RequestScopeSessionScope,...这样你就可以经常改变输入,但必须输入/在某个时候离开的范围被定义。一个例子见Custom Scopes

+0

1)是为时已晚,2)是1只是一个特例)。我也想过范围,但是这对于这样一个小问题,我宁愿干脆离开了DI为优美的缘故那么多样板: -/ – orsg 2013-05-01 13:41:59