티스토리 뷰
이전의 두개의 포스팅을 통해 의존성을 주입하는 여러가지 방법에 대해 알아봤고
dagger를 통해서 의존성을 주입하는 방법까지 알아보았다
이제 정말로 dagger의 강이 있다면 반은 건너왔다
여기서부터 고난이 시작될수도 있다
최대한 설명을 쉽게 풀어서 써보겠지만 얼만큼이나 전달이 될지 모르겠다
그렇지만 우리는 계속 앞으로 나아가야하기에
중요한 개념중의하나인 subcomponent를 알아보자
이전의 예제에서 로그인 플로우(LoginActivity에 의해서 관리되는)는 2개의 프래그먼트를 가지고 있다
상황에 따라 얼마든지 여러개의 프래그먼트를 사용할수 있다
로그인 플로우의 모든 프래그먼트에서 같은 LoginViewModel의 인스턴스를 사용하려고 한다
하지만 그렇다고 @Singleton 어노테이션을 LoginViewModel에서 사용하기는 영 깔끔하지 못하다
@Singleton 어노테이션을 붙이면 앱을 사용하는 동안 계속 같은 인스턴스를 전달받게 되는데
새로운 로그인 플로우가 시작될때는 다른데이터가 담겨있는 LoginViewModel의 인스턴스를 재활용하는것이 아니라
새로운 LoginViewModel을 받고 싶기 때문이다
즉 LoginViewModel은 다음과 같은 조건을 필요로 한다
1. LoginViewModel은 로그인 플로우가 끝나면 메모리에서 해제되어야 한다
2. LoginViewModel은 로그아웃이나 다른 상황에 따라 새로운 인스턴스를 사용해야할수도 있다
즉 LoginViewModel은 LoginActivity와 생애주기를 맞추면된다
이전 포스팅에서 dagger가 아닌 직접 의존성을 주입하는 방법을 알아보았을때
LoginContainer를 만들어서
LoginActivity가 onCreate될때 생성하고
onDestroy 할때 해지하는것을 해보았다
이제 dagger로 그때 만들었던 LoginContainer를 만드는것을 해볼것이다
새로운 component가 필요하다(subgraph라고도 표현할수 있겠다)
LoginComponent는 ApplicationComponent에 접근할수 있어야한다
ApplicationComponent는 많은 의존성을 제공할수 있는데
그중 하나가 UserRepository이고
LoginViewModel은 UserRepository에 의존적이기 때문이다
그래서 dagger subcomponent 기능을 사용하게 되는데
서브컴포넌트는 부모컴포넌트의 그래프를 상속받기 때문에
서브컴포넌트는 부모컴포넌트의 리소스들을 공유할수 있게 된다
그러므로 부모 컴포넌트에서 제공할수 있는 의존성을 subcomponent도 주입받을수 있다
@Component 어노테이션을 @Subcomponent로 바꿔주면된다
여기서 한가지 더 해야할것이 있다
@Comoponent 를 사용할때는 우리가 직접 해당 component의 인스턴스를 생성하는 Factory를 만들어줄필요는 없었는데(물론 그렇게도 할수 있다)
서브컴포넌트는 반드시 부모컴포넌트인 ApplicationComponent가 LoginComponent를 어떻게 만들면되는지 알도록
해야하므로 Factory를 구현해야한다
그리고 LoginComponent가 ApplicationComponent의 서브컴포넌트인것을 알려줘야 한다
1. SubcomponentModule을 만들고 서브컴포넌트 클래스를 subcomponents 속성값으로 넣어준다
2. 만든 모듈을 ApplicationComponent에 추가한다
이제 더이상 ApplicationComponent는 LoginActivity에 의존성을 직접 주입할 필요가 없어졌다
LoginActivity에 대한 책임은 LoginComponent가 가지고 있다
3. loginComponent를 외부로 노출시켜서 다른곳에서 이것을 가져다쓸수 있게 한다
프로젝트를 빌드하면 ApplicationComponent와 LoginComponent를 사용할수 있는데
ApplciationComponent는 앱의 생명주기에 맞춰서 메모리에 존재한다
그렇다면 LoginComponent는 어떠한 생명주기를 갖는것이 적절할까
LoginActivity의 하위 프래그먼트들에서 같은 LoginViewModel의 인스턴스를 사용해야하고
새로운 로그인 플로우가 시작되었을때는 다시금 LoginViewModel을 새로 생성하게 하기 위해서는
LoginActivity가 바로 LoginComponent의 알맞는 생명주기이다
그래서 우리가 applicationComponent를 application 클래스에 넣었던 것처럼
LoginComponent를 LoginActivity에 참조시켜보자
LoginComponent는 액티비티의 onCreate()때 생성된다
그리고 이것은 암묵적으로 액티비티가 종료될때 함께 종료될것이다
LoginComponent는 요청할때마다 반드시 같은 LoginViewModel 인스턴스를 제공해야한다
스코프 어노테이션을 LoginComponent와 LoginViewModel에 사용해서
같은 LoginViewModel 인스턴스를 받을수 있도록 보장해야한다
하지만 @Singleton 어노테이션은 이미 부모 컴포넌트에서 사용했기때문에
우리는 다른 이름의 스코프 어노테이션을 만들어야한다
이름을 @LoginScope라고 지어도 좋겠지만, 완벽한방법은 아니다
이런식으로 목적에 맞는 이름을 짓게 되면 향후에
@SignupScope, @SettingsScope와 비슷한 범위의 스코프를 계속해서 만들어야 하기 때문이다
비슷한 스코프 개념을 가지고 있는 다른기능들에서도 이 스코프를 사용하기 위해서
@ActivityScope라고 지어보자
자 이제 이렇게 함으로서 LoginViewModel을 쓰는 다른 프래그먼트들에도 inject를 할때 같은
LoginViewModel의 인스턴스가 주입되게 되었다
같은 @ActivityScope를 가졌기 때문에
dagger를 통해 LoginViewModel을 주입받을때
LoginActivity에서건 LoginUsernameFragment에서건, LoginPasswordFragment에서건
같은 LoginViewModel 인스턴스를 받게 된다
대거의 그래프는 이렇게 그려질것이며
하얀점은 unique한 인스턴스임을 나타낸다
그래프를 살펴보면
1. NetworkdModule은 ApplicationComponent에 포함되어있다
2. UserRepository는 ApplicationComponent에 남아있고 어디서든지 같은 인스턴스가 공유될것이다
3. LoginViewModel은 LoginComponent에 포함되어있다
LoginComponent에 의해서 주입될것이고 ApplicationComponent에 속해있지 않기 때문에 ApplciationComponent에 의존적이지는 않다
UserRepository는 LoginComponent에도 의존적이게 되었다
서브컴포넌트를 생성하는 것은 각기 어플리케이션의 다른 부분을 캡슐화하는데에 좋은 방법이다
그리고 이렇게 서브컴포넌트로 분리하였기 때문에 확장가능하고,
시작시점에 너무 많은 메모리를 들고 있지 않아도 되므로 성능적인 측면에서도 좋다
@Subcomponent의 설명하는 거의 모든 예제가 mvvm 아키텍쳐의 viewmodel을 가정하여 설명되고 있다
물론 mvvm의 viewmodel 개념이 서브컴포넌트를 설명하기에 매우 적합하기도 하다.
하지만 현 시점에서는
안드로이드가 AAC라고 불리는 안드로이드 아키텍쳐 컴포넌트로서
https://developer.android.com/topic/libraries/architecture/viewmodel?hl=ko
viewmodel 기능을 공개했다
클래스 수명 주기를 고려하여 UI 관련 데이터를 저장하고 관리할수 있는데 특화된 기능이라고 간단하게 설명할수 있는데
우리가 예제를 통해 만들었던 viewmodel의 역할처럼
UI를 위한 데이터를 담아두는 역할을 하는 ViewModel 클래스를 제공해준다
이 클래스를 통해 UI가 제거되거나 다시 생성되도 UI데이터가 손실되지 않고
다시 viewmodel을 통해 가져올수 있도록 설계가 되어있다
우리는 이 기능을 이용함으로서 굳이 dagger를 통해 직접 viewmodel의 수명주기를 관리하지 않아도 된다
하지만 꼭 viewmodel용이 아니더라도 서브컴포넌트는 dagger를 활용함에 있어서
서브 그래프를 그린다는 중요한 개념중의 하나이므로 반드시 기억하고 넘어가도록 하자
'WEB2.0 > 프로그래밍' 카테고리의 다른 글
dagger에 context를 주입하는 좋은 방법 @BindsInstance (0) | 2019.12.17 |
---|---|
dagger의 @binds 활용 (0) | 2019.12.16 |
dagger를 통한 의존성 주입 안드로이드 실전 (0) | 2019.12.14 |
의존성 주입에 대한 기본 이해 (3) | 2019.12.13 |
아이폰 앱개발시 다크모드 비활성화 설정 추가하기 (0) | 2019.12.09 |
- Total
- Today
- Yesterday
- 트위터
- 아이폰
- android
- 애플
- 공모전
- 경진대회
- 소프트웨어
- php
- AWS
- 앱스토어
- 대학생
- 구글
- CSS
- iPhone
- 안드로이드
- Apple
- 아이디어
- JavaScript
- 게임
- 창업
- 모바일
- 네이버
- 자바스크립트
- 앱
- 웹표준
- 벤처
- 어플리케이션
- 스마트폰
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |