본문 바로가기

안드로이드

[Android] ContributesAndroidInjector란?

개요

이번 포스팅에서는 Android용 대거(Dagger)의 annotation 중 하나인 ContributesAndroidInject에 대해서 알아본다.

 

 

기존 방식

Android에서 대거를 활용할 때 Activity, Fragment 같은 안드로이드 시스템에서 생성하는 객체들에 의존성을 주입할 때 직접 각 컴포넌트를 생성하고 inject하는 코드까지 작성하는 보일러 플레이트가 존재했다.

 

// StorageModule에 대한 정보를 추가한 컴포넌트 정의
@Component(modules = [StorageModule::class])
interface MainComponent {
    
    // 이 컴포넌트에 의해 주입을 원하는 클래스
    fun inject(activity: RegistrationActivity)
}
class RegistrationActivity : AppCompatActivity() {

	//RegistrationComponent 객체를 저장하고 프래그먼트들이 접근 가능하게 한다.
    lateinit var mainComponent: MainComponent

    override fun onCreate(savedInstanceState: Bundle?) {

        // 대거에게 의존성 주입을 요청한다.
        mainComponent = (application as MyApplication).appComponent.mainComponent().create() 
		mainComponent.inject(this)
        
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_registration)
    }

    ...

만약 다른 Activity나 Component에서도 StorageModule 관련 클래스들을 주입 받고 싶다면, 각각에 대해 MainComponent를 생성해주고 inject 메소드를 호출하는 일을 반복해야될 것이다.

 

이를 간단하게 처리할 수 있는 방법이 바로 ContributesAndroidInjector이다.

 

 

ContributesAndroidInjector

ContributesAndroidInjector는 반환 유형에 대해 AndroidInjector를 생성시켜주는 인터페이스이다. 해당 injector는 Subcomponent로 구현되며 Module의 Component의 자식이 된다.

Generates an AndroidInjector for the return type of this method. The injector is implemented with a Subcomponent and will be a child of the Module's component.

 

@Module
abstract class ActivityBuilder{
    @ContributesAndroidInjector(modules = MainActivityModule.class)
    abstract MainActivity mainActivity();
    
    @ContributesAndroidInjector(modules = RegistrationActivityModule.class)
    abstract RegistrationActivity registrationActivity();
}

@ContributesAndroidInject를 통해 MainActivity와 관련된 서브 컴포넌트가 생성되고, 해당 컴포넌트의 모듈로 MainActivityModule이 지정되었다.

 

그리고, Module은 그래프에 객체를 추가하는 역할을 한다. Module은 Component에 속해야되는데 해당 Activity를 공급해주는 컴포넌트는 최상위 컴포넌트인 AppComponent이다.

 

AppComponent.java

@Singleton
@Component(
        modules = {
                ActivityBuilder.class,
                AndroidSupportInjectionModule.class
        }
)
public interface AppComponent extends AndroidInjector<MyApplication> {
    @Component.Factory
    abstract class Factory implements AndroidInjector.Factory<MyApplication>
}

AppComponent는 AndroidInject<주입할앱>을 상속받아야 한다.

 

MyApplication.java

public class MyApplication extends DaggerApplication {

    @Override
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
        return DaggerAppComponent.factory().create(this);
    }
}

MyApplication은 DaggerApplication을 상속받아야 한다.

 

해당 과정을 통해 AndroidInject로 MyApp 객체를 주입하였다. 

 

MainActivity.java

public class MainActivity extends DaggerAppCompatActivity{
    @Inject
    Storage storage

    @Override
    protected void onCreate(Bundle savedInstanceState){
    	super.onCreate(savedInstanceState)
    }
}

이제 MainActivity에서는 간단하게 DaggerAppCompatActivity를 상속받는 과정을 통해 마음대로 의존성을 주입받을 수 있게 된다.