Dagger 2:从数据库

时间:2015-07-28 07:17:49

标签: android database singleton dagger-2

我正在开发一个Android应用程序并使用Dagger 2在我的活动/片段中注入一些对象作为单例。一些对象是从数据库加载的。

那么可以在后台加载数据库对象并在它可用时立即注入它吗?或者,当我用匕首初始化单身时加载它是没有问题的吗?或者,我可以将引用传递给活动/片段并在那里加载对象。

你对这个问题有什么看法?

1 个答案:

答案 0 :(得分:4)

这是一个有趣的问题,因为它涉及我认为是许多人从依赖注入(DI)开始面临的第一个问题:我应该注入的类型对象,我该怎么办? ,在您的情况下,我应该手动传递什么?

当你使用依赖注入(并且可能也是单元测试,但这是一个不同的故事)时,理解你正在设计的对象/类的类型的分类是很重要的:

  1. 服务:执行某些操作的对象,如业务逻辑。
    • 这些是你在单元测试中想要mock的东西。
  2. 价值对象(为了我们的讨论,还包括DTOs和实体......认为POCO或POJO):这些是保存信息的对象。通常是不可变的模型对象。值对象与服务没有任何依赖关系,即您永远不想向其中注入任何内容。
    • 你永远不会在单元测试中模仿这些对象!您可以使用具体类型,最好使用Test Data Builders来创建它们。
  3. 注意:这些是我对这些术语的快速解释。如果你在Domain Driven Design上读到一本书,你会发现更准确的定义,但我认为这应该足以讨论DI。

    Misko Hevery(AngularJS之父;-)提到这些术语,如“服务”过载,特别是在Android中,“服务”具有特定含义,所以他称之为值对象和服务 Newables Injectables 。我认为这是一个很好的建议。

    要将这些概念应用于您的案例:您将有一些类在数据库中查询相关对象。

    让我们说你正在谈论的对象是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是服务(可注入)。

    在您的代码中,您只想使用Dagger注入StudentRepository - 但您从不注入Student ...

    在不知道你正在做什么的更多细节的情况下很难给出进一步的建议,但希望这能回答你的问题:你必须将数据库实体读取从数据库传递到任何需要的地方,你不应该将它注入任何地方。