从 Dagger 2 移植到 Android Dagger 2.11

Port from Dagger 2 to Android Dagger 2.11

在将代码从 Dagger 2 移植到 Android Dagger 2.11 时,我不知道如何设置一些东西。在 Dagger 2 中,设置是这样的:

public class App extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        this.initializeInjector();
    }

    private void initializeInjector() {

        //this class should be auto-generated by Dagger on build
        this.applicationComponent = DaggerApplicationComponent.builder()
                .applicationModule(new ApplicationModule(this))
                .netModule(new NetModule())
                .build();
    }

    public ApplicationComponent getApplicationComponent() {
        return this.applicationComponent;
    }
}

然后您可以访问 applicationComponent 并且可以使用以下方法注入任何对象:

getApplicationComponent().inject(MyCustomObject);

在 Android Dagger 2.11 中,您不再这样做了。对于活动和片段,您可以使用 AndroidInjector.inject() 方法注入,但其他类型呢?让我们看下面的例子。我们有一个可以 post 个作业的 JobManager。这些作业被保存到一个文件中,当它们应该被 posted 时,它们首先被反序列化。问题是它的依赖关系当然没有设置。所以问题是:如何做到这一点?

public class JobManager {

    private Context context;

    @Inject
    public JobManager(Context context) {
        this.context = context;
    }

    public void postJob(String jobId) {

        MyJob myJob = deserializePersistedJobFromFile(jobId);


        //((App) context).getApplicationComponent().inject(myJob); //This was the old way of doing injection
        AndroidInjector.inject(myJob); //This doesn't work - what to do now?

    }

    .
    .
    .

}

public class MyJob {

    @Inject
    ApiService apiService;

    .
    .
    .
}

写在 phone 上,如有错别字,敬请谅解。

TL;DR MyJob 需要一个采用 ApiService 而不是成员注入的 @Inject(ed) 构造函数,这没有意义吗? MyJob 不能拥有自己的构造函数有什么原因吗? (不知道这是否是 Android SDK class)。如果这不是答案,那么我还有另一个观察结果,即您的 JobManager 似乎在做 JobScheduler 所做的事情?除非它只是术语的混淆(即两者 "jobs")

在 Android 之外,它的生命周期唯一性依赖倒置最常见的用途是构造函数注入。在 Android 框架内学习 DI 模式并不是最好的介绍,您会陷入 'lying to the complier' DI 框架功能,该功能旨在简单地帮助摆脱遗留代码库(c.f . Dagger 1的静态注入或Guide的'private'成员注入).

作为旁注,我避免移动到 "Android Dagger",因为它似乎与代码的模块化分离背道而驰。我想我在这里还有更多要学习的东西,但现在 "Android Dagger" 的样板中断优势被我对松散耦合的功能模块以支持即时应用程序和完全模块化的代码库的需求所抵消。

希望能有所帮助。

您在使用 "old" 方法时是否遇到任何问题,让您想转向 "new" 方法?

我找不到使用静态 AndroidInjector class 执行依赖项注入的任何一项真正优势,但它确实增加了代码的复杂性。

因此,如果您没有非常具体的理由朝那个方向前进,我建议您继续使用 "old" 工作方法。

至于注入 non-Activity/Fragment classes,我认为你不应该为此使用 DI 框架。仅使用 Dagger 注入应用程序、Activity、片段和服务。此 post 中提供了更多信息:Dependency Injection in Android

您可以让 Dagger 注入一个 MembersInjector<T>,然后使用它来将依赖项注入到您自己的对象中...

public class JobManager {

    private Context context;

    @Inject
    public JobManager(Context context, MembersInjector<MyJob> jobInjector) {
        this.context = context;
    }

    public void postJob(String jobId) {

        MyJob myJob = deserializePersistedJobFromFile(jobId);
        jobInjector.inject(myJob);
    }

    .
    .
    .

}

我写了这篇文章,应该对你有帮助。它链接到 Github.

上的示例代码

https://proandroiddev.com/exploring-the-new-dagger-android-module-9eb6075f1a46

密切关注 AppModule 以及它如何跟踪 application,以便您可以将 application.getApplicationContext() 传递给 JobManager

的构造函数

使用 dagger android 库有优势:

1) 使用 dagger 违反了依赖注入原则 类 不应该知道依赖是如何注入的,这个违规可以使用 dagger android library

来修复

2) Dagger 代码可以从 android 个组件中解耦。

3) 无需初始化 Dagger 组件和调用 android 组件中的注入方法,因此可以实现简洁的代码,从而创建易于维护的应用程序。

您可以使用 Dagger android 组件(例如 DaggerActivity、DaggerApplication 和 DaggerFragment)将 Dagger 与 android 分离,并将 AndroidInjection.inject() 调用移动到中央位置,而不是分别调用以及每个 activity 和片段,通过在应用程序上使用 activity 生命周期回调。

您可以在 android 阅读有关匕首的详细说明 http://www.zoftino.com/android-framework-classes-dependency-injection-using-dagger-android