我尝试从Spring迁移项目,然后通过跟踪示例GitHub repo开始使用Dagger 2。
在Spring中,我可以在类级别使用注释来公开类的所有方法,包括void
方法。我想在Dagger 2中这样做,即我想提供' void
方法。
在下面的代码示例中,我可以将printRandomUUID
方法移动到Printer
接口。但是,我正在进行这项小练习,目标是迁移古典的Spring @Component
或@Service
。
什么是正确的方法?是否可以在组件或模块级别提供void方法?
public class Main {
interface Printer {
void printMsg(String msg);
}
static class ConsolePrinter implements Printer {
@Override
public void printMsg(String msg) {
System.out.println(msg);
}
}
@Singleton
@Component(modules = ConsoleModule.class)
interface HelloWorldApp {
Printer getPrinter();
//this doesn't compile -> java.lang.IllegalArgumentException: not a valid component method:
void printRandomUUID();
}
@Module
static class ConsoleModule {
@Provides
Printer providePrinter() {
return new ConsolePrinter();
}
//this doesn't compile -> @Provides methods must return a value (not void)
@Provides
void printRandomUUID() {
System.out.println(UUID.randomUUID().toString());
}
}
public static void main(String[] args) {
HelloWorldApp app = DaggerMain_HelloWorldApp.create();
app.getPrinter().printMsg("Hello");
System.out.println("-");
//app.printRandomUUID();//here i want a void method to be consumed, from the component.
}
}
答案 0 :(得分:3)
这是不可能的(还)。与Spring不同,Dagger仅通过检查Component接口和Modules来配置。这意味着Dagger @Component
方法必须match the format of the methods from the @Component
documentation,并且目前无法提供委托给其他实例的任意代码或方法。
这并不是说组件不能有空方法:它们可以,但它们需要是一个单参数方法,注入@Inject
- 带注释的方法和字段外部创建的实例。这些被称为members-injection methods,而不是void
,它们也可以返回它们接受的类型以便于链接。
从不同的角度来看,我认为,出于简单和正确的原因,将任意业务逻辑与Dagger创建的组件相结合是一个坏主意:
new
一样不合适。 (是否应通过DI图提供每一个对象是另一天的争议话题。)如果我按原样进行迁移,我会在HelloWorldApp上创建一个名为HelloWorldMethods的类,并将我放在HelloWorldApp上的所有方法转移到该类上。如果这是Spring迁移中的常见模式,您甚至可以为它定义一个本地约定(例如,FooComponent附带FooMethods或FooUtil)。最后,如果你想隐藏Dagger实现细节(如在外部API中),你也可以编写自己的类来包装和使用你的Component,将重要的方法委托给内部Component并提供你需要的任意实现。