简体   繁体   English

将依赖项注入Singleton Dagger 2.11

[英]Inject dependencies into Singleton Dagger 2.11

I have application-level scoped Singleton classes TaskRepository and AppConfig , which have dependencies of singleton types. 我有应用程序级作用域的Singleton类TaskRepositoryAppConfig ,它们具有Singleton类型的依赖关系。 In my activity, instance of TaskRepository is injected, but all its fields are null. 在我的活动中,注入了TaskRepository实例,但其所有字段均为空。

Application Class 应用类别

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 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 Class 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 AppConfig类别

@Singleton
public class AppConfig {

    @Inject
    Context mContext;

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

Please highlight my mistakes... Any help will be appreciated. 请强调我的错误...任何帮助将不胜感激。 Thanks! 谢谢!

There are two main types of injection with Dagger 2 - field injection and constructor injection. 使用Dagger 2注入的主要类型有两种-字段注入和构造函数注入。 Field injection is where you annotate fields of a class like an Activity or Fragment with @Inject and then explicitly request injection from a Dagger 2 Component: 字段注入是在其中使用@Inject注释活动或片段等类的字段,然后从Dagger 2组件显式请求注入的地方:

 class MainActivity extends AppCompatActivity {

     @Inject TasksRepository tasksRepository;

     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         AndroidInjector.inject(this); //explicit request for injection
     }
 }

Note that without the explicit request for injection in line 2 of onCreate the field tasksRespository would remain null . 注意,在onCreate的第2行中,如果没有显式的注入请求,则taskRespository字段将保持为null

For classes instantiated by the Android OS like Activity or Application field injection is appropriate. 对于由Android OS实例化的类,例如Activity或Application字段注入是合适的。 For others, including your repositories, it is preferable to use constructor injection. 对于其他人,包括您的存储库,最好使用构造函数注入。 Why? 为什么? When you are testing you can pass in test doubles through the constructor and stub behaviour or verify on the test doubles. 测试时,您可以通过构造函数和存根行为传递测试双打,也可以验证测试双打。

So to get it working you should refactor your TasksRepository to use constructor injection: 因此,要使其正常工作,您应该重构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;
    }

Note that this step will highlight any mistakes you have made in setting up your object graph. 请注意,此步骤将突出显示您在设置对象图时犯的任何错误。 So if Dagger 2 cannot provide any of the 3 parameters in the construtor for TasksRepository it will let you know with a compile-time message. 因此,如果Dagger 2无法在TasksRepository函数中提供3个参数中的任何一个,它将通过编译时消息通知您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM