DI与Dagger2,添加到图表或从图表中获取?

时间:2016-01-07 22:29:14

标签: android dependency-injection architecture dagger-2

使用Dagger2,以下两个实现的优点和缺点是什么:

1)

public class MyReceiver extends BroadcastReceiver {
    Something something;
    @Override public void onReceive(Context context, Intent intent) {
        something = ((MyApplication) context.getApplicationContext())
            .getComponent().getSomething();
    }
}

@Component
public interface MyComponent() {
    Something getSomething();
}

2)

public class MyReceiver extends BroadcastReceiver {
    @Inject Something something;
    @Override public void onReceive(Context context, Intent intent) {
        ((MyApplication) context.getApplicationContext())
            .getComponent().inject(this);
    }
}

@Component
public interface MyComponent() {
    void inject(MyReceiver myReceiver);
}

1 个答案:

答案 0 :(得分:0)

tl; dr 转到选项2. @Inject您的字段。

如果您的对象可以通过注入构造函数(下面的示例)来创建,那么一定要选择选项2 ,因为必须编写除标记要与@Inject一起使用的构造函数。

// object can just be injected without any additional modules
// since all dependencies can be satisfied
public class Something {
    @Inject
    public Something() {}
}

因此,为了进一步回答这个问题,让我们专注于现场/方法注入。

只需使用@Inject注释即可使代码更简单。 选项2 会让您再次声明依赖项。

// dont't worry about where they come from
// or how they are created 
@Inject
Something mSomething;

@Inject
Foo mFoo;

public void onCreate() {
    ((Application) context.getApplicationContext())
        .getComponent().inject(this);
}

此外,出于测试目的,您可能希望通过仅使用TestComponent再次注入相同的对象来覆盖注入的字段。这也仅适用于选项2

@Test
void someTest() {
    // this is only possible with @Injected annotated fields
    testComponent.inject(activityUnderTest);
}

但是第一个选择!

1。选项主要用于公开依赖组件的依赖项,而不是与SubComponent组件混淆,后者始终具有对父图的完全访问权。

@Component
public interface MyComponent() {
    Something getSomething(); // exposes something
}

@Component(dependencies = {MyComponent.class})
public interface OtherComponent() {
    // can access something in modules
}

手动使用选项1意味着通过以编程方式从实际业务代码中获取依赖关系并更加努力地编写测试代码来自行处理依赖项注入,这是您尝试通过使用DI来避免的。