非活动Java类中的Dagger 2注入

时间:2016-02-24 14:51:58

标签: java android dependency-injection dagger-2

我正在尝试将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()?

2 个答案:

答案 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(只要可以提供SharedPreferenceManagerMyManager也可以实例化):

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

它被注入并起作用了!