Dagger 2 注入非 Activity Java class
Dagger 2 injection in non Activity Java class
我正在尝试将 Dagger2 用于 DI,对于 Activity/Fragment 相关的 classes,它在有 onCreate 生命周期事件的情况下工作得很好。现在我有一个普通的 Java class 我想注入它。任何关于如何去做的想法将不胜感激。我的代码如下所示:
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();
}
这是 class 我需要将 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() ?
您通常应该尽可能使用构造函数注入。对 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、改造等。如果手动创建,这就是依赖地狱。
所以我找到了这样的方法来做到这一点。
首先在您的 AppComponent 中执行:
interface AppComponent {
...
// getters
fun getMailgunService(): IMailgunService
}
然后在应用程序中创建
companion object { lateinit var INSTANCE: MyApp }
然后在你的 class 中你想从 dagger AppComponent 注入 IMailgun 服务的地方你可以做
private var service: IMailgunService
init {
val component = DaggerAppComponent
.builder()
.application(CRMApp.INSTANCE)
.build()
service = component.getMailgunService()
}
它被注入并且有效!
我正在尝试将 Dagger2 用于 DI,对于 Activity/Fragment 相关的 classes,它在有 onCreate 生命周期事件的情况下工作得很好。现在我有一个普通的 Java class 我想注入它。任何关于如何去做的想法将不胜感激。我的代码如下所示:
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();
}
这是 class 我需要将 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() ?
您通常应该尽可能使用构造函数注入。对 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、改造等。如果手动创建,这就是依赖地狱。
所以我找到了这样的方法来做到这一点。
首先在您的 AppComponent 中执行:
interface AppComponent {
...
// getters
fun getMailgunService(): IMailgunService
}
然后在应用程序中创建
companion object { lateinit var INSTANCE: MyApp }
然后在你的 class 中你想从 dagger AppComponent 注入 IMailgun 服务的地方你可以做
private var service: IMailgunService
init {
val component = DaggerAppComponent
.builder()
.application(CRMApp.INSTANCE)
.build()
service = component.getMailgunService()
}
它被注入并且有效!