简体   繁体   English

Dagger 2 - 注入非Android类

[英]Dagger 2 - injecting non Android classes

I'm implimenting Dagger 2 in my Android app. 我在我的Android应用程序中恭维Dagger 2 I have it setup in the following way: 我按以下方式设置它:

AppComponent.java AppComponent.java

@Singleton
@Component(modules = {
  AndroidInjectionModule.class,
  AndroidSupportInjectionModule.class,
  ActivityBuilder.class,
  AppModule.class,
  DataBaseDaoModule.class
})

public interface AppComponent {
  @Component.Builder
  interface Builder {
    @BindsInstance
    Builder application(Application aApplication);

    AppComponent build();
  }

  Application application();
  void inject(MyApplication aApplication);
}

AppInjector.java AppInjector.java

ublic class AppInjector {

  public static void init(MyApplication aApplication) {

    //Initialize dagger and inject the aApplication
    DaggerAppComponent.builder().application(aApplication).build().inject(aApplication);

    aApplication.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
      @Override
      public void onActivityCreated(Activity aActivity, Bundle aBundle) {
        handleActivity(aActivity);
      }

      @Override
      public void onActivityStarted(Activity aActivity) {
      }

      @Override
      public void onActivityResumed(Activity aActivity) {
      }

      @Override
      public void onActivityPaused(Activity aActivity) {
      }

      @Override
      public void onActivityStopped(Activity aActivity) {
      }

      @Override
      public void onActivitySaveInstanceState(Activity aActivity, Bundle aBundle) {
      }

      @Override
      public void onActivityDestroyed(Activity aActivity) {
      }
    });
  }

  private static void handleActivity(Activity aActivity) {
    if (aActivity instanceof HasActivityInjector) {
      AndroidInjection.inject(aActivity);
      Timber.d("injected Activity");
    }
    if (aActivity instanceof FragmentActivity) {
      ((FragmentActivity) aActivity).getSupportFragmentManager()
        .registerFragmentLifecycleCallbacks(
          new FragmentManager.FragmentLifecycleCallbacks() {
            @Override
            public void onFragmentCreated(FragmentManager fm, Fragment f,
                                          Bundle savedInstanceState) {
              if (f instanceof Injectable) {
                Timber.d("injected Fragment");
                AndroidSupportInjection.inject(f);
              }
            }
          }, true);
    }
  }
}

AppModule.java AppModule.java

Module(includes = ViewModelModule.class)
class AppModule {

  @Singleton
  @Provides
  ApiService providesApiService(OkHttpClient aClient, MyInterceptor aInterceptor) {

    //Build a Retrofit object here
  }

  @Singleton
  @Provides
  OkHttpClient providesOkHTTPClient(MyInterceptor aInterceptor) {
   //Setup OKHTTP here
  }
}

And finally in MyApplication.Java in the onCreate method I just call the AppInjector like so: AppInjector.init(this); 最后在onCreate方法的MyApplication.Java中,我只是像这样调用AppInjectorAppInjector.init(this);

All of this works and anything I put in my AppComponent's moduels, I can inject into Activities, Fragments and ViewModels . 所有这些工作以及我在AppComponent的模块中放置的任何内容,我都可以注入Activities, Fragments and ViewModels

However, I have cases where I would need a utility class, that depends on Application , for contex - and I use the utility class in various places. 但是,我有一些情况需要一个utility类,它依赖于Application ,用于contex - 我在各个地方使用实用程序类。 Or I will have a Manager class, that depends on Application, or needs something from AppModule. 或者我将有一个Manager类,它取决于Application,或者需要来自AppModule的东西。 However, since I use these classes outside of Activities, Fragments and ViewModels I cannot just inject. 但是,由于我在Activities, Fragments and ViewModels之外使用这些类Activities, Fragments and ViewModels我不能只注入。 How would I provide my utility classes with their dependencies and any other type of class - like a manager class? 我如何为我的utility类提供它们的依赖项和任何其他类型的类 - 比如管理器类?

My first thought was to create a UtilityComponent and a ManagerCompoent of sorts, however I have no idea how I would get them to work with anything in AppModuel or through my AppComponent . 我的第一个想法是创建一个UtilityComponent和一个ManagerCompoent ,但我不知道如何让他们在AppModuel或我的AppComponent

Please don't just use component.inject(myObject) for everything. 请不要只使用component.inject(myObject) Always prefer constructor injection or provide it from a module where you can do additional setup steps. 始终更喜欢构造函数注入,或者从可以执行其他设置步骤的模块提供构造函数注入。 .inject(myObject) is intended for Framework components where you don't have access to the constructor. .inject(myObject)适用于您无权访问构造函数的Framework组件。

My first thought was to create a UtilityComponent and a ManagerCompoent of sorts, however I have no idea how I would get them to work with anything in AppModuel or through my AppComponent. 我的第一个想法是创建一个UtilityComponent和一个ManagerCompoent,但我不知道如何让他们在AppModuel或我的AppComponent中使用它们。

You don't need a separate component for that. 您不需要单独的组件。 See below. 见下文。

However, since I use these classes outside of Activities, Fragments and ViewModels I cannot just inject. 但是,由于我在Activities,Fragments和ViewModels之外使用这些类,我不能只注入。

That has nothing to do with injection. 这与注射无关。 You're talking about scopes, and it sound like your utilities are a @Singleton . 你在讨论范围,听起来你的工具是@Singleton Your AppComponent is a @Singleton scoped component, hence it can be used to provide your utils, too. AppComponent@Singleton域组件,因此它可以用来提供您utils的,太。

However, I have cases where I would need a utility class, that depends on Application , for context 但是,我有一些情况需要一个实用程序类,它取决于Application ,用于context

If they are part of the @Singleton component, which has access to your Application, they can also be provided anywhere else. 如果它们是可以访问您的应用程序的@Singleton组件的一部分,那么它们也可以在其他任何地方提供。 No need for more components or anything. 无需更多组件或任何东西。 Just declare your dependencies and don't overthink it. 只需声明你的依赖关系,不要过度思考它。


Just declare your util, annotate it with @Singleton and mark the constructor with @Inject for constructor injection. 只需声明你的util,用@Singleton注释它,并使用@Inject标记构造函数以进行构造函数注入。 @Singleton ensures that it will be provided by your AppComponent and can access the Application on which it depends. @Singleton确保它将由您的AppComponent提供,并可以访问它所依赖的Application

@Singleton public class MyUtil {

  private Application application;

  @Inject public MyUtil(Application application) {
    this.application = application;
  }

}

And then you can just inject it in your Activities, Fragments, or even into other Utilities.... 然后你可以将它注入你的活动,片段甚至其他工具......

@Singleton public class MyUtilWrapper {

  private MyUtil myUtil;

  @Inject public MyUtilWrapper(MyUtil myUtil) {
    this.myUtil = myUtil;
  }

}

And you can inject either or both into your activity or fragment... 您可以将一个或两个注入您的活动或片段......

@Inject MyUtil myUtil;
@Inject MyUtilWrapper myUtilWrapper;

void onCreate(..) {
  AndroidInjection.inject(this);
}

You do not need any modules, provides methods, or components to provide simple classes. 不需要任何模块,提供了一些方法,或组件,以提供简单的类。 Just make sure to add the right scope! 只需确保添加正确的范围!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM