0

我有以下课程:

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不同的 JARQueueModuleQueueAdaptorDefaultQueueAdaptor因此后一个 JAR 在运行时依赖于前一个 JAR(显然)。

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

CacheAdaptor cacheAdaptor = new DefaultCacheAdaptor();

同上QueueAdaptor

碰巧的是,QueueAdaptor被注入了CacheAdaptor.

但是,DefaultCacheAdaptor它是自己对象树的“根”,应该始终CacheModule.

所以我问:我怎样才能从内部绑定DefaultCacheAdaptor到,但确保它本身被初始化/引导?CacheAdaptorQueueModuleDefaultCacheAdaptorCacheModule提前致谢!

4

1 回答 1

2

老实说,听起来这个问题实际上并不是 Guice 的问题,而是整个软件工程的标准问题:确保你的依赖项做他们声称要做的事情。QueueModule 不应该关心 DefaultCacheAdaptor 是否符合其一般合同。相反,为 DefaultCacheAdaptor 编写一个单元测试,以保证它自己引导,然后在 QueueModule 中使用它而不加考虑。

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

即使您要将两个 Injector 图合并为一个(例如,通过注入 Injector并调用createChildInjector),也几乎没有办法在编译时保证您在其他模块中需要的绑定将存在,因为Modules 在运行时工作。最好的办法是编写单元测试。您可以通过调用来更快地requireBinding失败,如果该特定依赖项最终没有在外部得到满足,这将在 Injector 创建时失败。

于 2013-09-03T21:11:07.370 回答