我正在尝试将Dagger2用于DI,它对于存在onCreate生命周期事件的Activity / Fragment相关类非常适用。现在我有一个普通的Java类,我想要注入它。任何关于如何去做的想法将不胜感激。我的代码看起来像这样:
BasicMoviesUsecaseComponent.java -
@PerActivity
@Component(dependencies = AppComponent.class, modules = BasicMoviesUsecasesModule.class)
public interface BasicMoviesUsecasesComponent {
void inject(PaymentsManager paymentsManager);
}
DatabaseModule.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);
}
}
AppComponent.java -
@Singleton
@Component(modules = {
ApplicationModule.class,
DomainModule.class,
DatabaseModule.class
})
public interface AppComponent {
Bus bus();
Realm realm();
DatabaseProvider dbProvider();
SharedPreferencesManager sharedPreferencesManager();
}
这是我需要将SharedPreferencesManager注入的类,我无法这样做:
MyManager.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()?
答案 0 :(得分:41)
您应该尽可能使用构造函数注入。对component.inject(myObject)
的调用主要用于无法自己实例化的对象(如活动或片段)。
构造函数注入基本上就是你已经做过的事情:
private class MyManager {
private SharedPreferencesManager manager;
@Inject
MyManager(SharedPreferencesManager manager){
this.manager = manager;
}
}
Dagger将为您创建对象并传入SharedPreferencesManager
。无需调用init或类似的东西。
真正的问题是如何获取 MyManager
的对象。为此,dagger将再次为您处理它。
通过用@Inject
注释构造函数,你告诉匕首如何创建该类型的对象。要使用它,只需将其注入或声明为依赖项。
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();
}
答案 1 :(得分:0)
我也遇到了这个问题。我在一个文本字段验证器中使用了MailgunService。该验证器的制作方式使我可以在XML布局中将其定义为app:rule="mailgun|email"
。
因此,基本上,我在自定义视图实现中访问验证器,该验证器需要服务,并且我想使用匕首,以便不必创建所有这些httpclient,改造等。如果手动创建,这就是依赖关系。
因此,我找到了一种执行此操作的方法。
首先在您的AppComponent内部进行:
interface AppComponent {
...
// getters
fun getMailgunService(): IMailgunService
}
然后在应用程序中创建
companion object { lateinit var INSTANCE: MyApp }
然后在您想从匕首AppComponent注入IMailgun服务的类内部进行
private var service: IMailgunService
init {
val component = DaggerAppComponent
.builder()
.application(CRMApp.INSTANCE)
.build()
service = component.getMailgunService()
}
它被注入并起作用了!