使用匕首2进行注射的方法

我还没有设法找到一个很好的解释/例子使用Dagger 2进行方法注入。有人可以帮我理解吗?

例:

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

因此,如果我用 注释我的方法,我是否正确地假设方法签名中的参数将注入对象图中定义的对象?那么,我该如何在我的代码中使用此方法呢?当我进行方法调用时,它仍然会期望我提供所有参数,这有点违背了目的。@Inject

更新:

因此,据我所知,如果我调用 Dinner 对象,则 Dinner 对象将可用,假设我的 DinnerComponent 是这样设置的: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();
}

如何在组件中指定哪个晚餐是哪个?


答案 1

与使用 Dagger 方法注入的方式相比,Dagger 方法注入的一个根本区别是 Dagger 方法注入只是在构造或注入 DI 就绪对象时发送依赖项的另一种方式,这意味着@Inject注释的方法意味着 Dagger 在构造时调用一次,而不是从你自己的代码中调用。.这使得您不太可能 -annotate 、 或任何其他具有有意义的副作用或返回值的方法。相反,将方法注入视为构造函数式注入的施工后机会。@InjectmakeDinnerfryDinner

(当然,您始终可以在方法级别练习一般依赖关系注入,将依赖项传递到方法调用中,以便方法本身不必创建它们。但是,这不是Dagger对方法注入的定义所指的意思,也无助于支持这种情况。

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 注释的方法,并使用 Dagger 图中的参数调用它。

无论是否使用 Chef 都是 Dagger 可构造的:除非您有@Inject注释的构造函数或@Provides方法,否则您将无法直接从组件获取 Chef,但您可以在组件上创建一个接收已构造实例的方法。该组件方法将使用字段和方法注入来为该 Chef 提供他们可能需要的成分、提供者、可选组件或懒惰。有关详细信息,请参阅@Component成员注入器文档。voidChef

请注意,在任何情况下,对象图上都不会显示可用!将@Inject添加到方法或字段只是告诉Dagger,作为注入过程的一部分,它应该填充该字段或使用给定的依赖项调用该方法。如果要使 Dinner 在对象图上可用,则需要对 Dinner 构造函数@Inject注释,或者在馈送到组件中的模块上放置一个@Provides或@Binds方法。Dinner

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


答案 2

对方法进行注释会给出 Dagger 指令,以便在创建对象后立即执行此方法 — 就在构造函数调用之后。当您需要为某些内容使用完全构造的对象时,这很有用。本文中有一个方法注入的示例。@Inject

你说这种方法的参数将由Dagger提供是正确的,这就是为什么你不应该自己调用这个方法。


推荐