我正在尝试将Dagger2用于DI,它非常适合存在onCreate生命周期事件的活动/片段相关类。现在我有一个想要注入的普通 Java 类。关于如何去做的任何想法将不胜感激。我拥有的代码如下所示:
基本电影用例组件.java -
@PerActivity
@Component(dependencies = AppComponent.class, modules = BasicMoviesUsecasesModule.class)
public interface BasicMoviesUsecasesComponent {
void inject(PaymentsManager paymentsManager);
}
数据库模块.java -
@Module
public class DatabaseModule {
@Provides @Singleton
Realm provideRealmInstance(Context context) {
return Realm.getInstance(context);
}
@Provides @Singleton
DatabaseProvider provideDatabaseInstance(Realm realm) {
return new DatabaseProvider(realm);
}
@Provides @Singleton
SharedPreferences provideSharedPrefs(Context context) {
return context.getSharedPreferences(context.getPackageName()+"_prefs", Context.MODE_PRIVATE);
}
@Provides @Singleton
SharedPreferencesManager provideSharedPreferencesManager(SharedPreferences sharedPreferences) {
return new SharedPreferencesManager(sharedPreferences);
}
@Provides @Singleton
PaymentsManager providePaymentsManager(SharedPreferencesManager sharedPreferencesManager) {
return new PaymentsManager(sharedPreferencesManager);
}
}
应用组件.java -
@Singleton
@Component(modules = {
ApplicationModule.class,
DomainModule.class,
DatabaseModule.class
})
public interface AppComponent {
Bus bus();
Realm realm();
DatabaseProvider dbProvider();
SharedPreferencesManager sharedPreferencesManager();
}
这是我需要注入共享首选项管理器的类,但我无法这样做:
我的经理.java -
private class MyManager {
private SharedPreferencesManager manager;
@Inject
MyManager(SharedPreferencesManager manager){
this.manager = manager;
}
private void initializeDependencyInjector() {
BMSApplication app = BMSApplication.getInstance();
DaggerBasicMoviesUsecasesComponent.builder()
.appComponent(app.getAppComponent())
.basicMoviesUsecasesModule(new BasicMoviesUsecasesModule())
.build().inject(PaymentsManager.this);
}
}
如何调用 initializeDependencyInjector() ?
通常应尽可能使用构造函数注入。对component.inject(myObject)
的调用主要用于您无法自己实例化的对象(如活动或片段)。
构造函数注入基本上是你已经做的:
private class MyManager {
private SharedPreferencesManager manager;
@Inject
MyManager(SharedPreferencesManager manager){
this.manager = manager;
}
}
dagger将为您创建对象并传入您的SharedPreferencesManager
。无需调用 init 或类似的东西。
真正的问题是如何获得MyManager
的对象。为此,dagger将为您处理。
通过使用@Inject
注释构造函数,您可以告诉 dagger 它如何创建该类型的对象。要使用它,只需注入它或将其声明为依赖项。
private class MyActivity extends Activity {
@Inject
MyManager manager;
public void onCreate(Bundle savedState){
component.inject(this);
}
}
或者只是向组件添加一个 getter(只要可以提供SharedPreferenceManager
,MyManager
也可以实例化):
@Component(dependencies = SharedPreferenceManagerProvidingComponent.class)
public interface MyComponent {
MyManager getMyManager();
}
我也遇到了这个问题。我有一个文本字段验证器中使用的MailgunService。这个验证器是以这样一种方式制作的,我可以在XML布局中将其定义为app:rule="mailgun|email"
。
所以基本上我正在自定义视图实现中访问验证器,这个验证器需要服务,我想使用dagger,以便不必创建所有这些 httpclient、改造等。如果手动创建,这是依赖地狱。
所以我找到了这样一种方法来做到这一点。
首先,在应用程序组件中,您需要执行以下操作:
interface AppComponent {
...
// getters
fun getMailgunService(): IMailgunService
}
然后在应用程序中,您制作
companion object { lateinit var INSTANCE: MyApp }
然后在您的类中,您想从daggerAppComponent注入IMailgun服务,您可以执行
private var service: IMailgunService
init {
val component = DaggerAppComponent
.builder()
.application(CRMApp.INSTANCE)
.build()
service = component.getMailgunService()
}
它被注入并且有效!