当前位置: 首页 > 面试题库 >

使用Dagger 2进行方法注入

顾跃
2023-03-14
问题内容

在使用Dagger 2进行方法注入方面,我还没有找到很好的解释/示例。有人可以帮我理解吗?

例:

@Inject
public Dinner makeDinner(Pasta pasta, Sauce sauce) {
    mPan.add(pasta);
    mPan.add(sauce);
    return mPan.cookDinner();
}

因此,如果用注释我的方法@Inject,是否可以正确地假定方法签名中的参数将注入对象图中定义的对象?那我该如何在代码中使用这种方法呢?当我进行方法调用时,仍然希望我提供所有参数,这将达到目的。

更新:

因此,据我了解DinnerComponent.dinner(),假设我的DinnerComponent的设置如下,则如果我调用,Dinner对象将可用:

@Component(modules = DinnerModule.class)
public interface DinnerComponent {
    Dinner dinner();
}

我的DinnerModule设置如下:

@Module
public class DinnerModule {
    public DinnerModule() {}

    @Provides
    Pasta providePasta() { return new Pasta(); }

    @Provides
    Sauce provideSauce() { return new Sauce(); }
}

如果我要炸晚餐怎么办?因此,让我们介绍一下这种方法:

@Inject
public Dinner makeDinner(Pasta pasta, Sauce sauce) {
    mPan.add(pasta);
    mPan.add(sauce);
    return mPan.fryDinner();
}

我如何在组件中指定哪一顿晚餐?


问题答案:

方法注入的一个根本区别与您似乎使用的方法不同,它是
方法注入只是Dagger
在构造或注入DI就绪对象时发送依赖项的另一种方法
,这意味着 @Inject注释的方法是意味着Dagger在构建时会被调用,而不是在您自己的代码中调用
。这使得@Inject-annotate
makeDinnerfryDinner或任何其他具有有意义的副作用或返回值的方法的可能性非常小。相反,将方法注入视为构造函数式注入的事后机会。

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;
  }

  /* Non-@Inject */ public Dinner cookDinner() {
    mPan.add(mPastaProvider.get());
    mPan.add(mSauce);
    return mPan.cookDinner();
  }

  /* Non-@Inject */ 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-Annotathtml" target="_blank">ion Dinner构造函数,或将@Provides或@Binds方法放在要馈入组件的模块上。

你为什么要用这个?考虑一种情况,其中对象是以反射方式创建的(例如,Android中的“活动”,“片段”和“视图”,或“可序列化的”对象),而您不希望公开@Inject字段。在这些情况下,可以通过在字段上进行注入来解决构造函数约束。同样,尽管我没有尝试过,但是您可以利用类层次结构来使用@Inject标记接口方法,以确保无论您是否在DI上下文中,都可以将某些依赖项作为对象的一部分传递给对象制备。



 类似资料:
  • 我试图将一组房间组件注入存储库,存储库本身使用Dagger2注入ViewModel(在片段中)。 代码如下。 片段: 视图模型: 我的存储库: 最后,对于我的匕首类,我有两个模块: 和我的AppComponent: Dagger编译正常,我可以访问并构建它。但是是不可访问的(检查类将其显示为私有),我需要实际注入依赖项的方法也是如此。结果我得到错误: 我该如何解决这个问题?

  • 问题内容: 我在Android应用程序中将Dagger2用于DI。我发现我必须为使用@Inject字段的每个类编写注入方法。有没有一种方法可以只注入父类,而不必在每个子类上调用inject?以活动为例。我有一个“ 每个活动都从中延伸”的内容。有没有一种方法,我可以在BaseActivity的组件中创建一个注入方法,然后在BaseActivity的onCreate中调用inject,子活动中的@in

  • 我学习了Dagger2,并尝试使用MVVM制作应用程序。我根据方案创建了Dagger类(模块、组件、BaseApplication),但当我尝试将QuotableAPI对象注入ViewModel时,Dagger不会生成DaggerAppComponent类(在ViewModel构造函数中没有QuotableAPI生成)。 报价视图模型 应用程序模块 应用组件 基础应用 ViewModelFacto

  • 我在android应用程序中使用Dagger2进行DI。我发现我必须为每个使用@inject字段的类编写inject方法。有没有一种方法,我可以只注入父类,这样我就不必对每个子类都调用注入?以活动为例。我有一个,每个活动都从它扩展。是否有一种方法可以在组件中为BaseActivity创建一个inject方法,并在BaseActivity的onCreate中调用inject,然后自动注入子活动中的@

  • 我有一组仅包含静态方法和单个私有构造函数的API类,因此它们无法实例化。但是,我希望第三方开发人员能够修改API的行为以满足他们的需求。 这是我目前为止的解决方案(通过静态setter方法进行依赖注入)。这是开发人员将使用的公共API类。如您所见,它依赖于< code>StaticApiImpl。 这是我自己编码的默认API实现。 这是第三方可能编写的默认实现的假设扩展版本: 开发者只需在插件初始

  • 我刚开始使用Dagger并尝试使用dagger2进行DI,但看起来它给我的活动注入了一个空演示器。下面是我的代码。 公共类TasksActivity扩展AppCompatActivity{