【问题标题】:Inject dependencies into Singleton Dagger 2.11将依赖项注入 Singleton Dagger 2.11
【发布时间】:2018-03-09 20:56:37
【问题描述】:

我有应用程序级范围的单例类 TaskRepositoryAppConfig,它们具有单例类型的依赖关系。在我的活动中,TaskRepository 的实例被注入,但它的所有字段都是空的。

应用类

public class MVPApplication extends Application implements HasActivityInjector {

    @Inject
    DispatchingAndroidInjector<Activity> activityDispatchingAndroidInjector;

    @Inject
    TasksRepository tasksRepository;

    @Inject
    AppConfig appConfig;

    private static MVPApplication instance;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        Realm.init(this);
        DaggerAppComponent
                .builder()
                .application(this)
                .realmBuilder(Realm.getDefaultInstance())
                .build()
                .inject(this);
    }

    @Override
    public DispatchingAndroidInjector<Activity> activityInjector() {
        return activityDispatchingAndroidInjector;
    }
}

应用组件

@Singleton
@Component(modules = {
        AndroidInjectionModule.class,
        AppModule.class,
        ActivityBindingModule.class})
public interface AppComponent extends AndroidInjector<DaggerApplication> {

    @Component.Builder
    interface Builder {

        @BindsInstance
        Builder application(Application application);

        @BindsInstance
        Builder realmBuilder(Realm realm);

        AppComponent build();
    }

    void inject(MVPApplication application);

    TasksRepository getRepository();

    AppConfig getAppConfig();

}

应用模块

@Singleton
@Module
public class AppModule {

@Provides
@Singleton
TasksRepository provideTasksRepository() {
    return new TasksRepository();
}

@Provides
@Singleton
AppConfig provideAppConfig() {
    return new AppConfig();
}
}

TaskRepository 类

@Singleton
public class TasksRepository implements RepositoryDatasource {

@Inject
Context mContext;

@Inject
AppConfig appConfig; //Singleton

@Inject
Realm realm; //Singleton

   //There is no constructor. Only public functions using fields

}

AppConfig 类

@Singleton
public class AppConfig {

    @Inject
    Context mContext;

   //There is no constructor. Only public functions using fields
}

请突出我的错误...任何帮助将不胜感激。谢谢!

【问题讨论】:

    标签: android dependency-injection singleton dagger-2 dagger


    【解决方案1】:

    Dagger 2 有两种主要的注入类型 - 字段注入和构造函数注入。字段注入是您使用 @Inject 注释 Activity 或 Fragment 等类的字段,然后从 Dagger 2 组件显式请求注入:

     class MainActivity extends AppCompatActivity {
    
         @Inject TasksRepository tasksRepository;
    
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             AndroidInjector.inject(this); //explicit request for injection
         }
     }
    

    请注意,如果onCreate 的第 2 行中没有明确的注入请求,则字段 tasksRespository 将保持为null

    对于由 Android 操作系统实例化的类,如 Activity 或 Application 字段注入是合适的。对于其他人,包括您的存储库,最好使用构造函数注入。为什么?在测试时,您可以通过构造函数和存根行为传入测试替身,或者在测试替身上进行验证。

    所以要让它工作,你应该重构你的 TasksRepository 以使用构造函数注入:

    @Singleton
    public class TasksRepository implements RepositoryDatasource {
    
        private final Context context;
        private final AppConfig appConfig; 
        private final Realm realm;
    
        @Inject
        TasksRepository(Context context, AppConfig appConfig, Realm realm) {
            this.context = context;
            this.appConfig = appConfig;
            this.realm = realm;
        }
    

    请注意,此步骤将突出显示您在设置对象图时所犯的任何错误。因此,如果 Dagger 2 无法在 TasksRepository 的构造函数中提供 3 个参数中的任何一个,它将通过编译时消息通知您。

    【讨论】:

    • 感谢您的详细解答。这是有道理的,并且像魔术一样工作!非常感谢:D 你关于字段和构造函数注入的观点是正确的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多