我有一个Java主应用程序,它有一些复杂的命令行参数。这些参数目前由CommandLineArgumentProcessor
类处理。这是我的代码当前的样子:
public static void main(String[] args) {
Injector injector = Guice.createInjector(new ConfigModule(), new WorkModule(), new ReportModule);
injector.getInstance(I_CommandLineArgumentProcessor.class).processArguments(args);
//Its not until here that I know if I should stub or not with this implementation
...
}
我现在正在实现一种方法来存根一些用于系统测试的类。为此,我需要交换Guice使用的一些绑定。然后在命令行上,我将指定某些标志来打开/关闭各种功能的存根。但是,我的问题是在创建注入器之前不会处理参数。
在创建进样器之前是否需要使用单独的逻辑来处理我的存根标记,然后有条件地创建适当的进样器?我对这种方法犹豫不决,因为它将处理命令行参数的逻辑划分为两个代码区域。或者,是否有另一种(适当的)方法让Guice在创建注入器后替换对象图中的各种对象/子树?或者,我是否为命令行处理器配备了一个注入器,然后为其余模块创建另一个注入器?
答案 0 :(得分:3)
注入器的绑定一旦创建就是不可变的(尽管绑定本身可以是动态的)。我建议首先创建一个只绑定您需要执行命令行处理的注入器。然后执行命令行处理,获取标志,并在创建实际应用程序将使用的另一个注入器时使用它们。如果你需要绑定的东西能够执行应用程序其余部分所需的命令行处理,你可以创建第二个注入器作为第一个注入器的子注入器。
您可以执行其他一些奇怪的操作,例如设置命令行标志的可变单例并使用依赖于该对象的提供程序方法:
@Provides
protected Foo provideFoo(Config config) {
return config.isStubFoo() ? new StubFoo() : new RealFoo();
}
但我认为第一种方法更为可取。
答案 1 :(得分:1)
您是否考虑使用儿童注射器?从您的示例来看,您只需要根注入就可以获得I_CommandLineArgumentProcessor的实例。如果没有更多上下文,我建议使用创建I_CommandLineArgumentProcessor所需的最小绑定来指定根注入器。
然后,您可以将I_CommandLineArgumentProcessor与其他一些注入类似提供程序的类结合使用,以便返回要传递给createChildInjector方法的模块。