匕首2:将2个不同的范围注入一个对象

时间:2018-11-20 17:53:31

标签: android dagger-2

在有人开始将此问题标记为重复之前,我先说我已经检查了这个post,但是并不能解决我的问题。

正如标题所述,我需要在另一个对象中注入来自不同作用域的两个对象。 假设我们遇到下一种情况:

我们有一个屏幕,允许用户注册,然后在同一屏幕上,基于用户会话进行一些操作(例如:做一些同步)。

对于我的项目,我计划使用子组件。到目前为止,我基于此post具有下一个代码(简体):

@Singleton
@Component(modules = {AppModule.class})
public interface AppComponent {

  static AppComponent init(MyApplication application) {
    return DaggerAppComponent.builder()
        .appModule(new AppModule(application))
        .build();
  }

  UserSessionComponent plusUserSessionComponent(UserSessionModule userSessionModule);

  void inject(MyApplication application);
}

@Module
public class AppModule {

  private MyApplication myApplication;

  public AppModule(@NonNull MyApplication myApplication) {
    this.myApplication = myApplication;
  }

  @Provides
  @Singleton
  public AppSignUp provideAppSignUp() {
    return new AppSignUp();
  }
}

@UserSessionScope
@Subcomponent(modules = {UserSessionModule.class})
public interface UserSessionComponent {

  static UserSessionComponent init(AppComponent appComponent,
      UserSession userSession) {
    return appComponent.plusUserSessionComponent(userSession);
  }

  void inject(MyApplication myApplication);
}

@Module
public class UserSessionModule {

  private UserSession userSession;

  public UserSessionModule(@NonNull UserSession userSession) {
    this.userSession = userSession;
  }

  @Provides
  @UserSessionScope
  public UserSessionSyncHelper provideUserSession(UserSession userSession) {
    return new UserSessionSyncHelper(userSession);
  }


  @Provides
  @UserSessionScope
  public UserSessionSync provideUserSession(UserSessionSyncHelper userSessionSyncHelper) {
    return new UserSessionSync(userSessionSyncHelper);
  }
}

现在,为了简单起见,假设我有一个组件(活动,视图模型,演示者等),它具有以下两个依赖关系:

public MyActivity extends AppCompatActivity {

  @Inject
  AppSignUp appSignUp;

  @Inject
  UserSessionSync userSessionSync;

  public void onCreate(Bundle savedInstanceState) {
    //to inject appSignUp
    MyApplication.getAppComponent().inject(this);
  }

  public onUserCreated(UserSession userSession) {
    //to inject userSessionSync
    MyApplication.getUserSessionComponent().inject(this);
  }
}

我的问题是Dagger在第一次注入时会抱怨,因为AppModile没有userSessionSync。所以问题是,我该如何解决这个问题?匕首在这种情况下有什么功能吗?

到目前为止,我只能想到下一个解决方案:

使UserSessionSync独立于Dagger框架和内部

public class UserSessionSync {
  @Inject
  UserSessionSyncHelper userSessionSyncHelper;

  public UserSessionSync(){
    MyApplication.getUserSessionComponent().inject(this)
  }
}

我认为,这不是解决此问题的好方法。

1 个答案:

答案 0 :(得分:0)

使用Dagger-Android尝试,效果很好。另外,AppSignUp确实不需要模块。使用@Singleton的@Inject构造函数()可以做到。在后台,它使用子组件。

@Module
abstract class AppModule {

    @Module
    companion object {

        @JvmStatic
        @Provides
        @Singleton
        fun providesAppSignUp() = AppSignUp()

    }
}

@Singleton
@Component( modules = [AndroidSupportInjectionModule::class, ActivityBindingModule::class, AppModule::class] )
interface AppComponent : AndroidInjector<MainApplication>

@Module
interface ActivityBindingModule {

    @UserScope
    @ContributesAndroidInjector( modules = [MainActivityModule::class] )
    fun mainActivity() : MainActivity
}

@Module
abstract class MainActivityModule {

    @Module
    companion object {

        @JvmStatic
        @Provides
        @UserScope
        fun providesUserSession() = UserSession()
    }
}

class UserSession

class AppSignUp

@Scope
annotation class UserScope

class MainApplication : DaggerApplication() {

    @Inject
    lateinit var appSignUp : AppSignUp

    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().build()
    }

}

class MainActivity : DaggerAppCompatActivity() {

    @Inject
    lateinit var appSignUp: AppSignUp

    @Inject
    lateinit var appSignUp1: AppSignUp

    @Inject
    lateinit var userSession: UserSession

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}