我有一些看起来像这样的代码(简化):
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的直接依赖,我无法弄清楚如何获得接受目录对象的工厂方法。
答案 0 :(得分:3)
有两种方法可以做到这一点:
让Guice绑定您的目录。这可能意味着将Catalog实例传递给您的Module,但Modules可以使用任意数量的构造函数参数,因此没有问题。在您的模块中,这将如下所示:
bind(Catalog.class).toInstance(myVeryExpensiveCatalog);
如果您确实需要根据未知或可更改的目录实例创建一个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
可以位于任何名称的位置 - 这些只是我喜欢的名称和位置。
现在,在AssistedInject documentation,您会看到他们也会拨打implement
。如果Reader
是一个接口,你只需要这样做,因此Guice知道要构建什么样的具体类来满足create
的返回类型。
希望这有帮助!