Guice:注入另一个模块绑定的类?

时间:2013-09-03 18:59:27

标签: java dependency-injection guice

我有以下课程:

public class CacheModule extends AbstractModule {
    @Override
    protected void configure() {
        bindConstant().annotatedWith(Names.named(TIMEOUT")).to(60);
        // ...etc.
    }
}

public class DefaultCacheAdaptor implements CacheAdaptor {
    private CacheModule bootstrapper = new CacheModule();

    @Named("TIMEOUT") private int timeout;

    // other fields omitted for brevity

    public DefaultCacheAdaptor() {
        super();

        Injector injector = Guice.createInjector(bootstrapper);

        @Named("TIMEOUT") int t = injector.getInstance(Integer.class);
        setTimeout(t);
    }
}

public class QueueModule extennds AbstractModule {
    @Override
    public void configure() {
        bind(CacheAdaptor.class).to(DefaultCacheAdaptor.class);
    }
}

public class DefaultQueueAdaptor implements QueueAdaptor {
    private QueueModule bootstrapper = new QueueModule();

    private CacheAdaptor cacheAdaptor;

    public DefaultQueueAdaptor() {
        super();

        Injector injector = Guice.createInjector(bootstrapper);

        setCacheAdaptor(injector.getInstance(CacheAdaptor.class));
    }
}

CacheModule / CacheAdaptor / DefaultCacheAdaptor位于与QueueModule / QueueAdaptor / DefaultQueueAdaptor不同的JAR中,因此后者JAR在运行时依赖于前JAR(显然)。

以这种方式编码的目的是允许CacheModule在用户写入时DefaultCacheAdaptor下提升/注入整个对象图:

CacheAdaptor cacheAdaptor = new DefaultCacheAdaptor();

同样适用于QueueAdaptor

只有这样发生才会QueueAdaptor注入CacheAdaptor

但是,DefaultCacheAdaptor是其自有对象树的“根”,CacheModule始终注入。

所以我问:如何从DefaultCacheAdaptor内部CacheAdaptor绑定QueueModule,但要确保DefaultCacheAdaptor本身由CacheModule初始化/引导{1}}?提前致谢!

1 个答案:

答案 0 :(得分:1)

说实话,听起来这个问题实际上并不是Guice之一,而是整个软件工程中的标准问题:确保您的依赖关系做他们声称要做的事情。 QueueModule不应该关注DefaultCacheAdaptor是否符合其总契约。相反,为DefaultCacheAdaptor编写一个单元测试,保证它自己引导,然后在没有第二个想法的情况下在QueueModule中使用它。

这尤其正确,因为DefaultCacheAdaptor具有完全不相关的注入树。您应该能够不透明地使用DefaultCacheAdaptor,并停止关于QueueAdaptor及其实现细节。它的引导是其实现的一部分,而不是它的API。

即使您要将两个Injector图合并为一个(例如injecting the Injector并调用createChildInjector),但在编译时保证绑定您的方法很少因为Module在运行时工作,所以在其他模块中需要存在。你最好的选择是编写单元测试。您可以通过调用requireBinding来更快地失败,如果该特定依赖关系不会在外部得到满足,则会在Injector创建时失败。