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

它被注入并且有效!