Dagger2注入一个没有@Inject构造函数的ViewModel

时间:2018-04-23 23:40:23

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

我有大量的Android ViewModel类,它们往往有很多依赖项(大多数是来自Room的DAO,每个SQLite表一个)。有些人有超过10个依赖项。

这很好,但是@Inject构造函数带有参数,并且只包含样板代码来设置构造函数参数中的注入成员。

我想切换到“常规”注入成员,使用@Inject注释单独识别,就像其他(哑)类一样。

这与Android相关的类失败(尽管ViewModels被宣传为非Android依赖,例如他们不使用Android框架),例如活动和片段。

解决方法是使用工厂,该工厂使用漂亮的ApplicationHasActivityInjector等接口从HasServiceInjector类注入。

Dagger没有提供任何HasViewModelInjector,所以如果我坚持单独注入成员而不是注入构造函数,这就是我给出的内容:

  

错误:[dagger.android.AndroidInjector.inject(T)]如果没有@Inject构造函数或@ Provide-annotated方法,则无法提供XXXViewModel。此类型支持成员注入,但不能隐式提供。

如果我创建一个具有@Provides注释的模块来创建ViewModel,则不会注入单个成员。

我是否遗漏了某些内容(我的最后一句话是我的问题中最重要的一句话),或者根本无法注入成员,而 注入构造函数?

一些代码。

我想要的是什么:

class MyViewModel extends ViewModel {
    @Inject
    MyDao myDao;
}

与我需要做的事情:

class MyViewModel extends ViewModel {
    private final MyDao myDao;

    @Inject
    MyViewModel(MyDao myDao) {
        this.myDao = myDao;
    }
}

第一个代码块(我想要的)在模块中需要这个方法:

@Provides
MyViewModel provideMyViewModel() {
    return new MyViewModel();
}

但在这种情况下,myDao字段为空。如何注入@Inject - 注释成员?

我想避免使用第二块代码,如果我需要注入很多成员,那么往往会产生一个带有很多参数的庞大构造函数。

1 个答案:

答案 0 :(得分:3)

有多种注射方式,我认为你指的是注射。与构造函数注入不同,必须手动触发场注入。为此,请使用视图模型作为参数在组件中定义方法。

void inject(ViewModel viewModel)

然后从您的视图模型构造函数中调用此方法。

class MyViewModel extends ViewModel {
    private final MyDao myDao;

    @Inject
    MyDao myDao;

    public MyViewModel() {
        MyComponent mycomponent = DaggerMyComponent.....
        myComponent.inject(this);
    }
}