Dagger 2:何时使用构造函数注入,何时使用字段注入?

2024-04-25

我有点懒,过去几乎完全使用现场注入。我只是提供空的构造函数,放入我的 @Inject 字段,我的一切看起来都很好很简单。然而,字段注入有其权衡,因此我设计了一些简单的规则来帮助我决定何时使用字段以及何时使用构造函数注入。如果我的逻辑有错误或者您有其他注意事项需要添加,我将不胜感激。

首先进行一些澄清,以便在同一页面上:

构造函数注入:

@Inject
public SomeClass(@Named("app version") String appVersion,
                    AppPrefs appPrefs) {...

与现场注入相同:

public class SomeClass {
    @Inject
    @Named("app version") String mAppVersion;

    @Inject
    AppPrefs appPrefs;

规则 1:如果我不控制对象的创建,则必须使用字段注入(想想 Android 中的 Activity 或 Fragment)。如果某些(非匕首感知)框架正在创建我的对象并为我处理它,我别无选择,只能在收到实例后手动注入它。

规则 2:如果该类在/可能在另一个不使用 Dagger 2 的项目中使用,则必须使用构造函数注入。如果其他项目不使用 Dagger,它们就无法使用 DI,因此用户必须使用“旧”方式创建对象new.

规则 3:在使用类层次结构时首选构造函数注入,因为创建单元测试更容易。

澄清:

考虑以下使用字段注入的结构:

package superclass;

public class SuperClass {
    @Inject
    HttpClient mHttpClient;
    ...
}

.

package differentpackage;

public class SubClass extends SuperClass {
    public SubClass() {
    }
}

当我为以下内容创建单元测试时SubClass在目录中test/java/differentpackage我别无选择,只能启动整个 DI 基础设施,以便能够注入HttpClient。相反,如果我使用这样的构造函数注入:

public class SuperClass {
    private final HttpClient mHttpClient;

    @Inject
    public SuperClass(HttpClient httpClient) {
        mHttpClient = httpClient;
    }
}

在我的单元测试中我可以简单地:

HttpClient mockHttp = mock(HttpClient.class);

Subclass tested = new Subclass(mockHttp);

// tests 

所以基本上现在我处于另一个极端:我倾向于主要依赖构造函数注入,并且仅在“规则 1”适用时才使用字段注入。 我在构造函数注入方面遇到的唯一“问题”是,对于“最终”类,构造函数有时会变得参数超载,并且它们看起来冗长且丑陋,如下所示:

@Inject
public ModelMainImpl(@Named("app version") String appVersion,
                    AppPrefs appPrefs,
                    LoginPrefs loginPrefs,
                    @ForApplication Context appContext,
                    NetworkInfoProvider networkInfoProvider,
                    AndroidEventPoster androidEventPoster,
                    Session session,
                    ForgeExchangeManager exchangeManager,
                    HttpFunctionality httpFunctionality,
                    @Named("base url") String baseUrl,
                    @Named("forge result producer") ResultProducer<ForgeExchangeResult> resultProducer
                    ) {

伙计们,在构造函数注入和字段注入之间选择的规则是什么?我遗漏了一些东西,我的逻辑有问题吗?


使用构造函数注入。如果不能,请使用属性注入。

规则 1 似乎没问题,就像装饰或属性一样,您可以使用 Property(field) 注入。

规则 2 似乎没问题,因为谁使用你的类,他们就必须遵循你的构造函数。他们可能不知道他们也必须侵犯您的财产。

规则 3 它不仅仅有利于单元测试。这对于应用单一职责很有好处。更容易看到你的对象图。否则你会用属性隐藏它。

如果我们提出您的问题,是的,您的构造函数中有很多参数。但是解决方案不是属性注入。您可以重构您的代码并使用聚合服务 http://blog.ploeh.dk/2010/02/02/RefactoringtoAggregateServices/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dagger 2:何时使用构造函数注入,何时使用字段注入? 的相关文章

  • 在 Java 中连接和使用 Cassandra

    我已经阅读了一些关于 Cassandra 是什么以及它可以做什么的教程 但我的问题是如何在 Java 中与 Cassandra 交互 教程会很好 如果可能的话 有人可以告诉我是否应该使用 Thrift 还是 Hector 哪一个更好以及为什
  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • 在 java 类和 android 活动之间传输时音频不清晰

    我有一个android活动 它连接到一个java类并以套接字的形式向它发送数据包 该类接收声音数据包并将它们扔到 PC 扬声器 该代码运行良好 但在 PC 扬声器中播放声音时会出现持续的抖动 中断 安卓活动 public class Sen
  • 给定两个 SSH2 密钥,我如何检查它们是否属于 Java 中的同一密钥对?

    我正在尝试找到一种方法来验证两个 SSH2 密钥 一个私有密钥和一个公共密钥 是否属于同一密钥对 我用过JSch http www jcraft com jsch 用于加载和解析私钥 更新 可以显示如何从私钥 SSH2 RSA 重新生成公钥
  • JAXb、Hibernate 和 beans

    目前我正在开发一个使用 Spring Web 服务 hibernate 和 JAXb 的项目 1 我已经使用IDE hibernate代码生成 生成了hibernate bean 2 另外 我已经使用maven编译器生成了jaxb bean
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • 无法解析插件 Java Spring

    我正在使用 IntelliJ IDEA 并且我尝试通过 maven 安装依赖项 但它给了我这些错误 Cannot resolve plugin org apache maven plugins maven clean plugin 3 0
  • 如何为俚语和表情符号构建正则表达式 (regex)

    我需要构建一个正则表达式来匹配俚语 即 lol lmao imo 等 和表情符号 即 P 等 我按照以下示例进行操作http www coderanch com t 497238 java java Regular Expression D
  • 从 127.0.0.1 到 2130706433,然后再返回

    使用标准 Java 库 从 IPV4 地址的点分字符串表示形式获取的最快方法是什么 127 0 0 1 到等效的整数表示 2130706433 相应地 反转所述操作的最快方法是什么 从整数开始2130706433到字符串表示形式 127 0
  • Java TestNG 与跨多个测试的数据驱动测试

    我正在电子商务平台中测试一系列商店 每个商店都有一系列属性 我正在考虑对其进行自动化测试 是否有可能有一个数据提供者在整个测试套件中提供数据 而不仅仅是 TestNG 中的测试 我尝试不使用 testNG xml 文件作为机制 因为这些属性
  • 加密 JBoss 配置中的敏感信息

    JBoss 中的标准数据源配置要求数据库用户的用户名和密码位于 xxx ds xml 文件中 如果我将数据源定义为 c3p0 mbean 我会遇到同样的问题 是否有标准方法来加密用户和密码 保存密钥的好地方是什么 这当然也与 tomcat
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • 将 List 转换为 JSON

    Hi guys 有人可以帮助我 如何将我的 HQL 查询结果转换为带有对象列表的 JSON 并通过休息服务获取它 这是我的服务方法 它返回查询结果列表 Override public List
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview

随机推荐

  • 安装期间初始化 user.config 或 app.exe.config

    我正在开发一个 NET WinForms 应用程序 它依赖于 user config 来存储各种有用的设置 例如 Intranet Web 服务 URL 我们希望能够在安装过程中导入自定义初始设置 其用例是 如果一家公司想要在 100 台计
  • Spring Boot - 微服务之间如何通信?

    我目前正在开发一个 Spring Boot 微服务项目 我创建了服务 每个服务都单独运行 这样 我需要一些服务来与其他服务进行通信 我怎样才能做到这一点 我看到一些关于此的博客使用 Netflix Eureka 云服务器来实现这一点 有什么
  • mysql中auto_increment(整数)的限制是多少

    我有一个mysql数据库 我在其中使用auto increment integer 你能告诉我它可以增加多少整数吗 我们如何提高auto increment的限制 的极限auto increment column 是列的大小 https d
  • PHP / OpenCart 2.2.0 - 创建自定义主题

    我今天开始在 OpenCart 2 2 中进行主题开发 我正在关注这篇文章 http code tutsplus com tutorials create a custom theme with opencart introduction
  • 类型错误:“itertools.combinations”对象不可下标

    当我尝试运行时 temp twoset2 x i 0 twoset x i 1 I get 类型错误 itertools combinations 对象不可下标 My code for x in range 0 64 for i in ra
  • 如何在动态更新时检测输入的值变化(Angular 6)

    我正在使用自定义指令和自定义管道对文本输入进行货币格式化 它适用于任何类型的直接用户输入 焦点 模糊 按键 但是 当值动态更改时 我似乎无法捕获更改事件 我也找不到可靠的主机侦听器事件列表 并且不知道如何捕获进入输入的任何事件 因此无法看到
  • 如何在 API 模式下使用 Doorkeeper 处理 OAuth 流程?

    场景很简单 A 仅限 Rails API带有 Doorkeeper 提供商的服务器 A 移动应用 and a SPA 假设是 React 想要使用电子邮件和密码注册和登录的用户 当你有一个正常的Rails 堆栈 你需要定义一个authori
  • RecyclerView 和 Picasso 图像滚动后消失

    我没有找到答案here https stackoverflow com questions 29564824 recyclerview disappearing images here https stackoverflow com que
  • GWT 和 Google 文档 API

    我正在使用 GWT 创建一个简单的应用程序 让教师可以轻松创建自己的课程 该应用程序将位于 Google App Engine 上 但我想将课程存储在用户的 Google 文档空间中 是否可以 据我所知 gwt 将 java 转换为 jav
  • 未捕获的错误:期望增强器是一个函数

    我试图从组件调用减速器并希望在组件中渲染它 但是当我尝试将减速器存储在 redux 的 createStore 方法中时 出现了上述错误 我的代码是这样的 import applyMiddleware compose createStore
  • Powershell Invoke-RestMethod 授权标头

    当调用一个Invoke RestMethod使用 Powershell 例如 Invoke RestMethod Method Get Uri https google com api GetData Headers headers and
  • Pandas 读取缺少一个标头的 csv

    我正在尝试使用 Pandas 读取 csv 文件 但第一列包含用逗号分隔的名字和姓氏 这会导致 Pandas 认为有 5 列而不是 4 列 因此最后一列现在没有标题 因此无法选择它 该文件如下所示 CustomerName ClientID
  • 在 SQL 中将字符串拆分为多行

    我继承了一个数据库 在努力使其更干净 更有用的过程中 我遇到了以下问题 将文件列移动到单独的表后 我现在的任务是将这些文件分成不同的行 请看我下面的例子 key jobid files 1 30012 file1 pdf file2 pdf
  • SSRS 聚合聚合

    这两天我都在用头撞墙 我的场景是这样的 我有一个记录集 在 SSRS 表中分为 4 组 他们是 StartPeriod gt Area gt Job gt Details 相关列包含两个不同的记录计数 一个是有错误的记录数 另一个是该组的记
  • SWI-Prolog 中的约束编程

    我想要一个包含三个元素 A B 和 C 的列表 L 并具有以下约束 use module library clpfd L A B C L ins 1 3 A B C 但是 它给出了一个错误 Syntax error Operator exp
  • UIViewController 弹出时未释放

    我有一个表视图 当选择一个单元格时 它将视图控制器推送到导航堆栈上 SAPostTableViewController postViewController SAPostTableViewController alloc initWithN
  • android kotlin java.io.FileNotFoundException:/storage/emulated/0/number.txt:打开失败:EACCES(权限被拒绝)

    我正在使用 kotlin 为 Android 10 编写一个应用程序 该应用程序必须读取名为number txt来自内部存储 但它总是失败 java io FileNotFoundException storage emulated 0 n
  • 在 Java 8 中使用 Java 7 比较器

    情况 我有一个 OSGi 项目 我正在尝试迁移到 Java 8 在我的项目中 我依赖于我 OSGi fied 的第三方库 只需添加MANIFEST MF文件并将元数据放入其中 这些库是从只读 SVN 存储库中签出的 因此我可以在需要时签出更
  • 在 iframe 中显示缩略图

    我在这方面还很陌生 我有以下内容iframe 我想做的就是让它发挥作用video1 1 但显示其中的图像video1 2 我尝试做的是 但这行不通 有简单的方法吗 iFrame 标记中没有 href 属性 看 http www w3scho
  • Dagger 2:何时使用构造函数注入,何时使用字段注入?

    我有点懒 过去几乎完全使用现场注入 我只是提供空的构造函数 放入我的 Inject 字段 我的一切看起来都很好很简单 然而 字段注入有其权衡 因此我设计了一些简单的规则来帮助我决定何时使用字段以及何时使用构造函数注入 如果我的逻辑有错误或者