在这个问题中,我谈到了Dagger2。 Dagger2基本上由组件和模块组成。这是一个例子:
假设我有一个界面:
public interface MyCoolService {
void run();
}
和可能的实施:
public class MyCoolServiceImpl {
@Override
void run() {}
}
我可以使用Dagger2生成链接实现与接口:
@Component(modules = {MyModule.class})
@Singleton
public interface Component {
MyCoolService getMyCoolService();
}
和
@Module
public class MyModule {
@Provides @Singleton
MyCoolService provideMyCoolService() {
return new MyCoolServiceImpl();
}
}
这是Dagger2的简要介绍。现在假设我有以下界面:
public interface MySecondCoolService {
void doCoolStuff();
}
代码中没有MySecondCoolServiceImpl
的{{1}}实现。相反,我有一个注释MySecondCoolService
来标记字段和方法。我创建了一个Annotation处理器,它收集所有这些注释并生成实现@JustForCoolStuff
的{{1}}。
我在注释处理器运行之前知道新接口MySecondCoolServiceImpl
。所以我可以将我的组件更改为:
MySecondCoolService
问题是我在代码中还没有实现,我不知道将由注释处理器生成的MySecondCoolService
实现的名称。因此,我无法在@Component(modules = {MyModule.class})
@Singleton
public interface Component {
MyCoolService getMyCoolService();
MySecondCoolService getMySecondCoolService();
}
中使用正确的实现来连接接口。我可以做的是更改我的注释处理器,以便它为我生成一个新模块。我的注释处理器可以生成一个模块(MySecondCoolService
),如下所示:
MyModule
再次MyGeneratedModule
由注释处理器生成。我在运行注释处理器之前无法访问它也不知道名称。
以下是问题:注释处理器不得不告诉Dagger2 Dagger2应该考虑一个新模块。由于注释处理器无法更改文件,因此无法扩展@Module
public class MyGeneratedModule {
@Provides @Singleton
MySecondCoolService provide MySecondCoolService() {
return new MySecondCoolServiceImpl();
}
}
注释并将其更改为以下内容:MyGeneratedModule
有没有办法以编程方式将@Component(modules = {MyModule.class})
添加到dagger2依赖关系图?我的注释处理器如何告诉Dagger2接口和实现之间应该有新的连接,如上所述?
FORAY: 我知道可以在Google Guice和Google Gin中完成类似的事情。这样做的项目是GWTP。那里有一位演示者:
@Component(modules = {MyModule.class, MyGeneratedModule.class})
对MyGeneratedModule
接口有public class StartPagePresenter extends ... {
@NameToken("start")
public interface MyProxy extends ProxyPlace<StartPagePresenter> {
}
...
}
注释。在@NameToken
中,您使用演示者和代理连接视图:
ProxyPlace
因为可以看到没有给出AbstractPresenterModule
接口的实现。由Generator生成的实现(类似于注释处理器,但用于GWT)。 Generator生成public class ApplicationModule extends AbstractPresenterModule {
bindPresenter(StartPagePresenter.class,
StartPagePresenter.MyView.class, StartPageView.class,
StartPagePresenter.MyProxy.class);
...
}
的实现并将其添加到指南/杜松子酒系统:
MyProxy
答案 0 :(得分:1)
有没有办法以编程方式将MyGeneratedModule添加到dagger2依赖图中?
是。在模块中使用构造函数参数。
@Module
public class MyModule {
private final MyCoolService serviceImpl;
public MyModule(MyCoolService serviceImpl) {
this.serviceImpl = serviceImpl;
}
@Provides @Singleton
MyCoolService provideMyCoolService() {
return new MyCoolServiceImpl();
}
}
在构建图表时初始化serviceImpl:
DaggerComponent.builder().myModule(new MyModule(serviceImpl)).build();
答案 1 :(得分:0)
嗯,看来你不得不求助于这个反思......
@Module
public class MyGeneratedModule {
@Provides @Singleton
MySecondCoolService provide MySecondCoolService() {
try {
return (MySecondCoolService) Class.forName("package.MySecondCoolServiceImpl").newInstance();
} catch (Exception ex) { ... }
}
}