Skip to main content

@Subcomponentを使ってActivityにDaggerでInjectする

ビッグデータを支える技術―刻々とデータが脈打つ自動化の世界 (WEB DB PRESS plus)

新品価格
¥3,256から
(2020/1/27 20:54時点)


[書評] Master of Daggerを読んだ
の続編

Daggerの本読んだだけだとよく分からないので
実際にInjectしてみた


ApplicationクラスにDaggerを定義

class MyApplication : Application(), HasAndroidInjector {
    //DispatchingAndroidInjectorがTとTのFactoryのMappingを返すらしい
    @Inject
    lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Any>

    override fun onCreate() {
        super.onCreate()

        DaggerAppComponent.create().inject(this)
    }

    override fun androidInjector(): AndroidInjector<Any> {
        return dispatchingAndroidInjector
    }
}

AppComponentはDaggerの一番最初のやつ

@Singleton
@Component(
    modules = [
        AndroidInjectionModule::class,
        AppModule::class,
        MainActivityModule::class
    ]
)
interface AppComponent {
    fun inject(app: MyApplication)
}

AppModuleにInjectされるインスタンスを書く

@Module
class AppModule {
    @Provides
    @Singleton
    fun provideMasterka(): Masterka {
        return Masterka()
    }
}

MainActivityModuleにInjectするActivityを記述

@Module(subcomponents = [MainActivitySubComponent::class])
interface MainActivityModule {

    @Binds //インタフェース経由でBindする
    @IntoMap //IntoMapでMapに入れてくれる。
    @ClassKey(MainActivity::class)
    fun bindMainActivitySubcomponentFactory(
        factory: MainActivitySubComponent.Factory
    ): AndroidInjector.Factory<*>
}

MainActivitySubComponentにInjectするFactoryを記載

//AndroidInjectorがTにメンバーをinjectする
//AndroidInjector.FactoryがTをオブジェクトクラスに登録する
@ActivityScope
@Subcomponent
interface MainActivitySubComponent : AndroidInjector<MainActivity> {

    @Subcomponent.Factory
    interface Factory : AndroidInjector.Factory<MainActivity>
}

Scopeは独自に定義

//annotation classは、Javaでは@interfaceに当たります。
@Scope
@Retention(AnnotationRetention.RUNTIME)
internal annotation class ActivityScope

MainActivity

class MainActivity : AppCompatActivity() {
    @Inject
    lateinit var masterka: Masterka

    override fun onCreate(savedInstanceState: Bundle?) {
        AndroidInjection.inject(this)
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)
        if (savedInstanceState == null) {
            supportFragmentManager.beginTransaction()
                    .replace(R.id.container, MainFragment.newInstance())
                    .commitNow()
        }


        Log.e("masterka", "masterka:$masterka")
    }

}

InjectするMasterka

class Masterka {
}

これでInjectされましたとさ
なかなか難しいなぁって感想です
ここからAndroid Supportを使ったりFragmentにinjectしたりしていく予定
続くよ

関連記事:

Pocket