我什么时候应该使用Factory <t>而不是Provider <t> </t> </t>

时间:2014-02-14 11:35:54

标签: java dependency-injection dagger

Dagger文档显示使用Provider<Filter>获取Filter个实例,这看起来非常有意义。

我正在编写一个ListAdapter来实例化Views,我希望Dagger能够注入。我很想在我的Provider<ViewType>中注入ListAdapter,并调用mViewProvider.get()来实例化视图。

然而,Dagger文档说:

  

注入Provider<T>可能会产生令人困惑的代码,并且可能是图表中错误范围或错误结构对象的设计气味。通常,您会希望使用Factory<T>Lazy<T>或重新组织代码的生命周期和结构,以便能够注入T

我可以看到我如何使用工厂,方式与使用辅助注射时的方式类似。

但是,使用我自己的Factory<T>使用Dagger的Provider<T>有什么好处,因为我必须自己写这个?

1 个答案:

答案 0 :(得分:10)

Provider<T>在系统中具有非常具体的含义。它是Graph管理对象的委托构造函数。 Provider<T>具有特定的保证/行为,我通常建议不要注入Provider<T>,除非您支持某些需要它的遗留情况。

Factory<T>就是一个例子--FooFactory更准确,因为这样做的目的是你不使用手工工厂,而是使用类似AutoFactoryhttp://github.com/google/auto)的东西来生成创建对象的工厂。然后你不必自己编写,但是在编写这些文档时还没有构建AutoFactory

最终,原因主要是代码清晰度和长期维护。使用dagger的实例管理作为事实上的实例工厂是可能的,但是有限,因为它只能用于注入依赖项的实例。如果不添加其他范围或图层,则无法支持调用堆栈依赖关系。在Guice中,这一事实经常导致人们通过使用自定义作用域玩游戏并将对象图和分层复杂化以获得一些免费代码,从而使用额外的作用域来调用对象实例(提供)依赖关系。

解决这个问题(在guice中)Assisted-Injection和(在Dagger中)创建了AutoFactory - 所以你可以做更加语义更清晰的东西,不依赖于框架内部,但是为你自动完成它

不使用Provider<T>是一种意见。如果您愿意, 可以免费使用,但不推荐练习。相反,我们建议使用类似AutoFactory的解决方案来获得更好的命名类型,在系统中具有更清晰的含义,可以支持更灵活地处理调用堆栈状态。