尝试开始使用Guice,并努力了解我的用例如何适应。
我有一个命令行应用程序,它需要几个可选参数。
假设我已经让工具显示了客户的订单,例如
order-tool display --customerId 123
显示ID为123的客户拥有的所有订单。现在,用户还可以指定用户名:
order-tool display --customerName "Bob Smith"
但查询订单的界面依赖于客户ID。因此,我们需要从客户名称映射到客户ID。为此,我们需要连接到客户API。因此,用户必须指定:
order-tool display --customerName "Bob Smith" --customerApi "http://localhost:8080/customer"
启动应用程序时,我想解析所有参数。在指定--customerApi
的情况下,我想在我的IoC上下文中放置一个CustomerApi单例 - 它由CLI arg和API URL参数化。
然后,当代码运行以按名称显示客户时 - 它会询问上下文是否具有CustomerApi单例。如果不是,则抛出异常,告诉CLI用户如果要使用--customerApi
,则需要指定--customerName
。但是,如果已经创建了一个 - 那么它只是从IoC上下文中检索它。
答案 0 :(得分:1)
听起来“可选地创建一个单身”并不完全是你在这里尝试做的。我的意思是,它是,但这很简单:
if (args.hasCustomerApi()) {
bind(CustomerApi.class).toInstance(new CustomerApi(args.getCustomerApi()));
}
要允许可选绑定,您可能需要annotate their use with @Nullable
。
我认为您真正的问题是如何构建应用程序以便您可以对其进行部分配置,使用配置来读取和验证某些命令行标志,然后使用标志来完成应用程序的配置。我认为最好的方法是使用儿童注射器。
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AModule(), new BModule(), ...);
Arguments arguments = injector.getInstance(ArgParser.class).parse(args);
validateArguments(arguments); // throw if required arguments are missing
Injector childInjector =
injector.createChildInjector(new ArgsModule(arguments));
childInjector.getInstance(Application.class).run();
}
Child injectors就像普通注射器一样,如果它们不包含给定的绑定本身,则会延迟到父级。您还可以阅读how Guice resolves bindings上的文档。