通常在使用 Dagger 2 和 android 时,我有以下内容:

@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {


    void inject(MainActivity activity);
}

public class MainActivity extends Activity {
    @Inject SharedPreferences mSharedPrefs;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((DemoApplication) getApplication())
                    .getComponent()
                    .inject(this);
    }
}

但最近我看到了这个:
@Singleton
@Component(modules = {ApplicationModule.class})
public interface ApplicationComponent {
    SharedPreferences getSharedPreferences();
}

public class MainActivity extends Activity {
    SharedPreferences mSharedPrefs;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSharedPrefs = ((DemoApplication) getApplication())
                .getComponent().getSharedPreferences();
    }
}

我省略了 DemoApplication 类和 Module 类,它们是标准的。

这两种方法有什么区别?两者的优缺点?也许是正确或错误的方式?

最佳答案

软件工程的 dependency inversion principle 建议我们应该尝试并依赖抽象而不是具体。

出于这个原因,您应该更喜欢 @Inject 注释(抽象)用于您的 Activity 中的字段注入(inject),而不是从 Dagger 组件(具体)调用配置方法。

为什么?您会注意到 @Inject 注释是 javax.inject 包的一部分。这是作为 JSR330 的一部分引入 Java 的依赖注入(inject) API 的标准。还有其他 DI 框架,例如 Guice 和 Toothpick,可以使用这些注释。如果以后必须切换 DI 框架,使用 @Inject 注释会更容易。是的,确实需要更改 DI 框架。 Roboguice 是一个最近被淘汰的流行 DI 框架的例子。

为了说明这一点,让我们以您的 Activity,添加一些依赖项,并提取这样的注入(inject)方法:

public class MainActivity extends Activity {
    @Inject SharedPreferences mSharedPrefs;
    @Inject Foo foo;
    @Inject Bar bar;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @VisibleForTesting
    protected void injectMembers() {
        ((DemoApplication) getApplication())
            .getComponent()
            .inject(this);
    }
}

一个狂野的(新的)DI 框架出现了!您现在必须更改您的应用程序才能快速使用它!您使用 JSR330。它 super 有效! (翻译:您可以重复使用您的 JSR330 @Inject 注释,因为新的 DI 框架支持它们)。如果您已更改为新的类似 Guice 的框架,您需要做的就是重写您的方法:
    @VisibleForTesting
    protected void injectMembers() {
        GuiceLikeInjector.getInjector(this).injectMembers();
    }

相比之下,如果您使用 .getSharedPreferences() 手动注入(inject)这些字段, getFoo() 就不是很有效 - 您必须更改很多代码行。

关于android - void injection(Activity activity) 和 SomeComponent getSomeComponent() 的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41843947/

10-12 00:23
查看更多