方法注入的一个根本区别与您似乎使用的方法不同,它是
方法注入只是Dagger
在构造或注入DI就绪对象时发送依赖项的另一种方法,这意味着 @Inject注释的方法是意味着Dagger在构建时会被调用,而不是在您自己的代码中调用
。这使得
@Inject-annotate
makeDinner,
fryDinner或任何其他具有有意义的副作用或返回值的方法的可能性非常小。相反,将方法注入视为构造函数式注入的事后机会。
public class Chef { private Provider<Pasta> mPastaProvider; private Sauce mSauce; @Inject public void registerIngredients( // can be named anything Provider<Pasta> pastaProvider, Sauce sauce) { // T and Provider<T> both work, of course mPastaProvider = pastaProvider; mSauce = sauce; } public Dinner cookDinner() { mPan.add(mPastaProvider.get()); mPan.add(mSauce); return mPan.cookDinner(); } public Dinner fryDinner() { mPan.add(mPastaProvider.get()); mPan.add(mSauce); return mPan.fryDinner(); }}在这种情况下,当您请求在Chef上进行注入时,Dagger将看到@ Inject-
annotated方法并对其进行调用。除非您具有@Inject注释的构造函数或@Provides方法,否则您将无法直接从Component获取Chef,但是
可以
void在Component上创建一个方法,该方法接收构造的
Chef实例并使用字段和方法注入为厨师提供他们可能需要的食材(或食材供应商)。(有关详细信息,请参见@Component和MembersInjector文档。)
请注意,在任何情况下
Dinner对象图都不会显示!在构造函数中添加@Inject告诉Dagger它可以使用该构造函数使对象在对象图上可用,但是在方法或字段中添加@Inject只是告诉Dagger作为注入过程的一部分,它应该填充该字段或调用具有给定依赖性的该方法。如果要在对象图上提供Dinner,则需要@
Inject-Annotation Dinner构造函数,或将@Provides或@Binds方法放在要馈入组件的模块上。
你为什么要用这个?考虑一种情况,其中对象是以反射方式创建的(例如,Android中的“活动”,“片段”和“视图”,或“可序列化的”对象),而您不希望公开@Inject字段。在这些情况下,可以通过在字段上进行注入来解决构造函数约束。同样,尽管我没有尝试过,但是您可以利用类层次结构来使用@Inject标记接口方法,以确保无论您是否在DI上下文中,都可以将某些依赖项作为对象的一部分传递给对象制备。



