我是stackoverflow和guice的新手。我不确定我想做什么是可能的guice,但我当然希望它是。
我的问题域是我正在尝试编写文档阅读系统。我已经为DocumentReader定义了一个接口。
public interface DocumentReader {
MetaData readDocument() throws Exception
}
我还定义了一个定义支持的文件类型(即扩展名)的枚举。
public enum FileType {
doc,
png,
txt,
}
我有每个FileType的实现,提供了如何解析该文件类型的详细信息。
public class MSWordReaderImpl implements DocumentReader {
// ....
}
public class PlainTextReaderImpl implements DocumentReader {
// ....
}
此时,我已经成功写了&测试了一个使用MapBinder& amp;的模块。 FactoryModuleProvider用于注入每个对象。存在的每个DocumentReader实现都单独添加到MapBinder。我希望的是,随着DocumentReader的其他实现的编写,我可以简单地使用它们支持的FileType来注释它们,并且GUICE将能够读取注释并将它们适当地添加到MapBinder(无需我每次添加更新模块)。我设想的是这样的:
@SupportedFileTypes( filetypes={ doc, docx } )
public class MSWordReaderImpl implements DocumentReader {
// ....
}
@SupportedFileTypes( filetypes={txt} )
public class PlainTextReaderImpl implements DocumentReader {
// ....
}
我已经多次阅读了GUICE文档,但我只是没有找到实现这一目标的方法(如果它甚至可能!)。任何帮助将不胜感激。
谢谢!
答案 0 :(得分:1)
了解其工作原理的最简单方法是查看Named和Names类的来源,以及它是used的来源。
首先创建一个RequiredFileType注释,
@Retention(RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@BindingAnnotation
public @interface RequiredFileType {
FileType value();
}
然后注释依赖于Document reader的类,
@Inject
ServiceRequiringWordReader(@RequiredFileType(doc) DocumentReader reader)
然后创建一个RequiredFileTypes实用程序,它等同于Names(代码省略),并在您的模块中编写代码,如
bind(DocumentReader.class)
.annotatedWith(RequiredFileTypes.for(doc))
.to(MSWordReaderImpl.class);
bind(DocumentReader.class)
.annotatedWith(RequiredFileTypes.for(docx))
.to(MSWordReaderImpl.class);
bind(DocumentReader.class)
.annotatedWith(RequiredFileTypes.for(txt))
.to(PlainTextReaderImpl.class);
答案 1 :(得分:1)
您可以让模块使用反射扫描类将进入的包,查找实现DocumentReader
并使用@SupportedFileTypes
注释的类。当找到一个时,将其添加到每个文件类型的MapBinder
。
如果您不想扫描类路径,您仍然可以通过编写如下方法来自行简化:
private void bindDocumentReaders(Class<? extends DocumentReader>... types) {
for (Class<? extends DocumentReader> type : types) {
FileType[] supportedFileTypes = type.getAnnotation(SupportedFileTypes.class)
.filetypes();
// add to MapBinder for each file type
}
}