非活动 Java 类中的 Dagger 2 注入



我正在尝试将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(只要可以提供SharedPreferenceManagerMyManager也可以实例化):

@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()
    }

它被注入并且有效!

最新更新