我正在开发一个 Android 应用程序并使用 Dagger 2 将一些对象作为单例注入(inject)到我的 Activity/fragment 中。一些对象是从数据库加载的。
那么是不是可以在后台加载数据库对象,有空就注入(inject)呢?还是在dagger初始化单例的时候直接加载就没问题了?或者我可以传递对 Activity/fragment 的引用并在那里加载对象。
您是如何解决这个问题的?
最佳答案
这是一个有趣的问题,因为它触及了我认为许多开始使用依赖注入(inject) (DI) 的人将面临的第一个问题:我应该注入(inject)什么类型的对象,我应该新,在你的情况下,我应该手动传递什么?
当您使用依赖注入(inject)(可能还有单元测试,但那是另一回事)时,了解您正在设计的对象/类类型的分类很重要:
- 服务:执行某些操作的对象,例如业务逻辑。
- 这些是你想要的东西mock在单元测试中。
- 值对象(为了我们的讨论,还包括 DTOs 和实体......想想 POCO 或 POJO):这些是保存信息的对象。通常是不可变的模型对象。值对象对服务没有任何依赖性,即你永远不想向它们注入(inject)任何东西。
- 你永远不会在单元测试中模拟这些类型的对象!您使用具体类型,理想情况下 Test Data Builders创建它们。
注意:这些是我对这些术语的快速解释。如果你在 Domain Driven Design 上读过一本书您会发现更精确的定义,但我认为这足以满足讨论 DI 的目的。
Misko Hevery (AngularJS 之父 ;-) 提到这些术语,如“服务”被重载,特别是在 Android 中,“服务”具有特定的含义,因此他将值对象和服务称为 Newables 和 分别注入(inject)剂。我认为这是个好建议。
要将这些概念应用到您的案例中:您将有一些类在数据库中查询相关对象。
假设您正在谈论的对象是 Student
,它可能有一些不可变的字段,大致如下:
class Student {
public final long id;
public final String firstName;
public final String lastName;
public final String email;
public Student(...) {
// assignment of fields here...
}
}
然后你会有一些对象从数据库中查询 Student
条目,让我们在这里说这样的 StudentRepository
:
class StudentRepository {
public List<Student> findAll() {
// db access here...
}
}
在此示例中,Student
是一个值对象(可更新),StudentRepository
是一个服务(可注入(inject))。
在您的代码中,您只想使用 Dagger 注入(inject) StudentRepository
—— 但您永远不会注入(inject) Student
...
在不了解您正在做的事情的更多细节的情况下很难提供进一步的建议,但希望这能回答您的问题:您必须将从数据库中读取的数据库实体传递到任何需要的地方,您不应该将其注入(inject)任何地方。
关于android - Dagger 2 : Inject object loaded from database,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31669747/