非活动 Java 类中的 Dagger 2 注入

我正在尝试将Dagger2用于DI,它对于活动/片段相关的类(其中存在onCreate生命周期事件)完全可以正常工作。现在我有一个普通的Java类,我想被注入。任何关于如何去做的想法将不胜感激。我拥有的代码如下所示:

BasicMoviesUsecaseComponent.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);

        }

}

AppComponent.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() ?


答案 1

通常应尽可能使用构造函数注入。对 的调用主要用于您无法自行实例化的对象(如活动或片段)。component.inject(myObject)

构造函数注入基本上是你已经做过的:

private class MyManager {
    private SharedPreferencesManager manager;

    @Inject
    MyManager(SharedPreferencesManager manager){
          this.manager = manager;           
    } 
}

匕首将为您创建对象并传入您的.没有必要调用 init 或类似的东西。SharedPreferencesManager

真正的问题是如何获得 的对象。要做到这一点,再次,匕首将为您处理它。MyManager

通过对构造函数进行注释,您可以告诉匕首它如何创建该类型的对象。要使用它,只需注入它或将其声明为依赖项。@Inject

private class MyActivity extends Activity {
    @Inject
    MyManager manager;

    public void onCreate(Bundle savedState){
        component.inject(this);  
    } 
}

或者只是向组件添加一个 getter(只要可以提供,也可以实例化):SharedPreferenceManagerMyManager

@Component(dependencies = SharedPreferenceManagerProvidingComponent.class)
public interface MyComponent {

    MyManager getMyManager();
}

答案 2

我也遇到这个问题。我有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()
    }

它被注射并且它起作用!


推荐