将依赖项注入Singleton Dagger 2.11

时间:2017-09-28 07:43:10

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

我有应用程序级范围的Singleton类 TaskRepository AppConfig ,它们具有单例类型的依赖关系。在我的活动中,注入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;
    }
}

AppComponent

@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();

}

的AppModule

@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 Class

@Singleton
public class AppConfig {

    @Inject
    Context mContext;

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

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

1 个答案:

答案 0 :(得分:2)

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 OS实例化的类,如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的construtor中提供任何3个参数,它将通过编译时消息通知您。