我正在尝试通过Dagger 2学习DI,并将其应用于我们的产品。带有注释的应用程序级的东西@Singleton
非常简单(例如SharedPreferences
)。在考虑我们的体系结构时,有一些本质上是异步的依赖项,我想这些依赖项的@ForSession
范围很广。
AccountManager
。在现有有效会话的情况下可以同步。如果没有现有会话,AccountManager
并且必须显示完整的登录流程,则可以是异步的。Endpoint
满足相关性的要求,以便我们的网络层知道在哪里可以找到API。Service
。仅在绑定Service
绑定完成时异步提供该组件。表示层应在收到这些项目的集合后进入。除了某种“正在加载”的显示之外,没有以上任何显示都无法做很多事情。
感觉这些依赖关系适合于@ProducerModule
and的用例@Produces
。我觉得我可以@Produces ListenableFuture<>
为每个依赖项提供方法,也许有一个SettableFuture<>
实现。执行所需的任何工作,呼吁set()
未来,就可以满足依赖性。
我讨厌的是生产者指南中的这句话。
如上面的示例所示,生产者模块可以与普通模块无缝使用,但要受到限制,即提供的类型不能取决于生产的类型。
对于“关于所有可用东西的门口演示”,我可以设想一个复合对象,该对象可以@Inject
与T
期货的解约一起使用。但这甚至合法吗?
这是我最接近的方法,但它明确地调用了复合方法的构造函数,而不是注入它。有办法做这种清洁剂吗?
@ProducerModule
public class SessionModule {
@Produces
@ForSession
static ListenableFuture<User> produceSignedInUser(SessionManager sessionManager) {
return sessionManager.getSignedInUserFuture();
}
@Produces
@ForSession
static ListenableFuture<BoundService> produceBoundService(SessionManager sessionManager) {
return sessionManager.getBoundServiceFuture();
}
@Produces
@ForSession
static CompositeSessionInfo produceComposite(User user, BoundService service) {
return new CompositeSessionInfo(user, service);
}
}
然后是组件:
@ForSession
@ProductionComponent(modules = SessionModule.class)
public interface SessionComponent {
ListenableFuture<CompositeSessionInfo> getCompsiteSessionInfoFuture();
}
在我想登机的地方,我可以做些类似的事情:
SessionComponent component = Dagger_SessionComponent.builder()
.executor(executor)
.build();
Futures.addCallback(component.getCompsiteSessionInfoFuture(),
new FutureCallback<CompositeSessionInfo> {
public void onSuccess(CompositeSessionInfo result) {
releaseTheHounds(result);
}
public void onFailure(Throwable t) {
reportError(t);
}
});
我对这部分的理解还遥遥无期吗?顺便说一句:为什么要@Produces
声明这些方法static
?这是必需的吗?(编辑:static
不一定要确定,但是我不确定意图是什么,而不是没有实例字段。Module
)
编辑:
我决定创建一个概念证明项目,从我的实际项目中抽象出我的想法。一切都按我的要求进行,只是我无法处理@Inject
任何@Produce
d项目,无论是最终结果“复合”数据还是中间结果。如果在组件中公开吸气剂,则可以得到它们,这就是我所做的。
我目前的计划是将@Producer
基于异步的东西放在一个单独的可注入模块中,然后将生成的依赖项输入到一个@Provides
样式模块中,该模块在其他地方输入以便可以对其进行@Inject
编辑。
编辑编辑:
更新了概念验证,使其具有共同的先验依赖关系,以更紧密地模仿我的需求。仍然不能@Inject。我相信这会尽我所能。
好吧,既然看来我会自己去做,我将发布自己的最终结论作为我自己的答案,以希望能帮助其他希望做类似事情的人。
我又更新了一次概念验证项目。现在,一旦满足了所有异步依赖关系,新的单个复合依赖关系就是一个实际的@Module,@Produced
通过新的重命名SessionProductionComponent
,该模块将注册为称为的组件SessionProvisionComponent
。该组件是一个标准,@Component
具有@Provide
通过标准@Inject
机制提供依赖关系的方法。
@Produces
@ForSession
public SessionProvisionModule produceSessionProvisionModule(Application app, SomeAsyncDependency someAsyncDependency, AnotherAsyncDependency anotherAsyncDependency) {
SessionProvisionModule module = new SessionProvisionModule(someAsyncDependency, anotherAsyncDependency);
((App) app).createSessionProvisionComponent(module);
return module;
}
现在在中MainActivity
,当我需要获取会话信息时,它看起来像这样:
App app = (App) getApplication();
sessionProductionComponent = app.getSessionProductionComponent();
if (app.getSessionProductionComponent() == null) {
sessionProductionComponent = app.createSessionProductionComponent(new SessionProductionModule());
}
Futures.addCallback(sessionProductionComponent.getSessionProvisionModuleFuture(),
new FutureCallback<SessionProvisionModule>() {
@Override
public void onSuccess(SessionProvisionModule result) {
app.getSessionProvisionComponent().inject(MainActivity.this);
}
@Override
public void onFailure(Throwable t) {
// handle failure
}
});
一旦Future
成功,我就可以inject()
像MainActivity
任何@Injected
人所期望的那样获得和带注释的字段的依赖关系。这样,我实际上可以拥有@Inject
after @Produce
。
不像我想要的那样干净,但是仍然比没有DI更好。现在,可以按任何顺序满足在任意时间范围内运行的任意数量的异步依赖项,并且一旦它们全部就绪,就可以Future
设置一个SessionProvisionComponent
,并准备将这些@Produced
依赖项注入依赖项。
多高兴。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句