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

匕首2:将用户输入的参数注入对象

邵研
2023-03-14
问题内容

说我有一个带对象的 Util 类-类 Validator的 一个实例。

由于我想避免在Util中实例化Validator类,因此我通过构造函数将其传递给:

public class Util {

   @Inject
   public Util(Validator validator) {

   }


}

我有一个提供Validator实例的模块:

@Provides
@Singleton
Validator provideValidator() {
    return Validator.getInstance();
}

以及一个Util类的实例:

@Provides
Util provideUtil(Validator validator) {
    return new Util(validator);
}

我有一个连接好的组件,可以给我一个Util实例:

Util getUtil()

所以在我的活动中,我可以这样称呼它:

Util myUtil = getComponent.getUtil();

所有这些都可以正常工作-myUtil在实例化时具有Validator类的适当实例。

现在,我想传递一个名为 address
的String变量(用户通过UI输入)。我想更改构造函数,以便同时传入Validator的实例和用户输入的String:

@Inject
public Util(Validator validator, String address) {

}

我只是无法理解如何传递第二个参数。有人可以告诉我如何吗?

理想情况下,我想实例化Util:

Util myUtil = getComponent.getUtil(txtAddress.getText());

问题答案:

几周前开始研究Dagger 2时,我遇到了与您相同的问题。我发现很难获得有关此信息(以及大多数其他与Dagger
2相关的问题)的信息,因此希望对您有所帮助!

最基本的答案是你不能。您正在寻找的是所谓的 辅助注入 ,它不是Dagger
2的一部分。其他一些依赖注入(DI)框架(例如Guice)确实提供了此功能,因此您可以进行研究。当然,仍有一些方法可以使用Dagger
2进行操作。

工厂工厂工厂

与DI结合使用的标准方法是使用Factory模式。基本上,您将创建一个可注入的工厂类,该类采用运行时参数,例如address它提供的对象创建方法的参数。

在您的情况下,您需要在实例化时将UtilFactoryDagger 2注入a Validator并提供一种create(String address)创建实例的方法UtilUtilFactory应该保留对的注入实例的引用,Validator以便它具有Utilcreate方法中创建实例所需的一切。

许多此类工厂的接线代码可能很麻烦。您绝对应该看一下AutoFactory,它可以减轻一些负担。Guice的辅助注入似乎与Dagger
2 + AutoFactory非常相似(尽管使用了更好的语法糖)。

更多模块/组件

在这种情况下,我怀疑这是您要执行的操作,但是您 可以
仅创建一个提供地址的模块(并实例化一个新组件)。您不必为每个可能的地址创建一个新的@Module类。相反,您可以仅将地址作为参数传递给模块的构造函数。您可以使用teano建议的@
BindsInstance-annotation获得类似的结果。

我不确定这是否是反模式。在我看来,在某些情况下,这似乎是一条可以接受的路线,但是仅当您实际上使用相同的地址(例如,“许多”对象的初始化)时才可以。您绝对不希望为每个需要注入的对象实例化新组件
新模型。它效率不高,而且如果不注意,最终将获得比没有Dagger更高的样板代码。

请勿(始终)使用DI:可注射与可注射

一些了解DI框架时,这是对我来说非常有用是实现了使用DI框架并 不能 意味着你必须DI初始化 所有
的对象。作为经验法则:注入在编译时知道的并且与其他对象有静态关系的对象;不要注入运行时信息。

我认为这是关于该主题的好帖子。它介绍了“新产品”和“可注射产品”的概念。

  • 注入 是DI图根附近的类。这些类的实例是您期望DI框架提供和注入的对象的类型。管理类型或服务类型的对象是注射剂的典型示例。
  • 可更新 对象是位于DI图边缘的对象,或者甚至根本不属于DI图的一部分。IntegerAddress等是newables的例子。

从广义上讲,可再生能源是被动的对象,没有必要注入或嘲笑它们。它们通常包含应用程序中的“数据”,并且仅在运行时可用(例如,您的地址)。新产品不应保留对可注射产品的引用,反之亦然(该文章的作者将其称为“可注射/可分离新产品”)。

实际上,我发现在注射剂和新药之间进行明确区分并不总是容易或可能的。不过,我认为它们是很好的概念,可用于您的思考过程。在为项目添加另一个工厂之前,请三思而后行!

对于您的情况,我认为将其Util视为可注射的内容并将地址作为可更新的内容是有意义的。这意味着该地址不应属于Util该类。如果您想使用实例Util作为例如validate
/ …地址,则只需将要验证的地址作为参数传递给validate / …方法。



 类似资料:
  • 我想在单元测试模块中使用我的领域管理器。我做的 然后我想实现 但是realmManager为空。如何使用匕首2编写简单的模块测试?我用了匕首模拟,但没有用。我的模块包含 我尝试了谷歌的一切,但我不知道如何从图形中注入对象。

  • 我正在使用Dagger 2,在为我的类实现测试时,模块中的generate singleton providers存在一些问题。 所以我有两个问题。 > 我不能使用构造函数注入,因为有一个默认的构造函数。如何从测试模块中获取Foo? 在和中,如何确保在运行每个测试时创建的新实例? 谢谢

  • 我目前正在尝试将匕首2集成到一个Android应用程序中。我的项目设置如下: 库 应用程序(取决于库) 在我的library项目中,我定义了一个类,以后我将把它注入到库和app项目中需要它的其他类(活动和常规类)中。 我也是这么想的,因为实际上myManager总是空的。很明显,它的构造函数也从来没有被调用过,所以我想我一定遗漏了一些配置方面的东西?或者也许我误解了文档,它根本不是这样工作的?My

  • 我有一个库项目/模块,Android应用程序和普通java应用程序都使用它。在Dagger 1中,此项目/模块具有属性。其中有一个@Inject字段,任何类实现或@Provides方法都不能满足该字段。其想法是强制具有的“顶部”模块提供特定于系统的实现 举个例子:在library项目中,我有一个ActLogin活动,它有字段。此字段的值在登录到服务器时使用。ActLogin由使用此库的多个应用程序

  • 在一个android、kotlin项目中,看到这个< code>@set:Inject,但找不到一个好的解释。有人知道吗?

  • 我正在尝试为我的navControl ler提供匕首柄。但是我使用的方法不起作用。我想提供navControl ler以便通过构造函数注入将其注入我的片段中。 我还创建了FragmentWorks类,以便通过构造函数注入我的依赖项。我知道是这里的问题,但我不知道正确的解决方案… 感谢您的帮助,谢谢! 原因:java.lang.ClassCastException:com.example.app。应