Guice后期绑定/辅助注入的问题

时间:2012-09-20 12:39:44

标签: dependency-injection guice

我有一些看起来像这样的代码(简化):

public Reader newInstance(Catalog catalog) {
    Mapper mapper = new Mapper(catalog);
    return new Reader(mapper)
}

public main() {
    // expensive operation
    Catalog catalog = readCatalogFromDatabase();

    Reader reader = Reader.newInstance(catalog);
    // do stuff with reader
}

如何重新设计这个以便我仍然创建目录,但Guice创建了Reader和Mapper?我尝试使用辅助注射,但由于目录不是Reader的直接依赖,我无法弄清楚如何获得接受目录对象的工厂方法。

1 个答案:

答案 0 :(得分:3)

有两种方法可以做到这一点:

  1. 让Guice绑定您的目录。这可能意味着将Catalog实例传递给您的Module,但Modules可以使用任意数量的构造函数参数,因此没有问题。在您的模块中,这将如下所示:

    bind(Catalog.class).toInstance(myVeryExpensiveCatalog);
    
  2. 如果您确实需要根据未知或可更改的目录实例创建一个Reader,那么您的预感就是使用辅助注射。这就是我要看的样子:

    class Reader {
      interface Factory {
        Reader create(Catalog catalog);
      }
    
      @Inject Reader(@Assisted Catalog catalog, OtherDependency etc) {
        this.catalog = catalog;
      }
    }
    
    class YourModule extends AbstractModule {
      @Override public void configure() {
        install(new FactoryModuleBuilder().build(Reader.Factory.class));
      }
    }
    

    然后你可以注入Reader.Factory并通过致电readerFactory.create(catalog);来吸引读者。请注意,create可以命名为任何名称,Factory可以位于任何名称的位置 - 这些只是我喜欢的名称和位置。

  3. 现在,在AssistedInject documentation,您会看到他们也会拨打implement。如果Reader是一个接口,你只需要这样做,因此Guice知道要构建什么样的具体类来满足create的返回类型。

    希望这有帮助!