-
Hilt 관련 리펙토링 기록 (@binds @Provides 차이 , UsecaseModule)Android & Kotlin 2023. 1. 8. 15:39
구조설명 (클린 아키텍처)
1. 클린아키텍처 구조에서 Hilt 를 통해 의존성 주입을 사용하고 있었다.
2. 이때 Repository (Interface) 의 주입을 위해 RepoisotyModule 을 만들어 사용했고 @Provides 를 사용해왔었다.
3. 그리고 Usecase 에서 Ropository 와 ErrorHandler 에 의존했고 이에 따라 각각 UsecaseModule, NetowrkModule 을 정의해주어 사용했다.class GetSomeUseCase( private val repository: Repository, private val errorHandler: ErrorHandler ) : BaseUseCase() {...} @ErrorHandler @Provides @Singleton fun provideErrorHandler( @HttpClient http: OkHttpClient, appStorage: AppStorage ): ErrorHandler = NetErrorHandlerImpl( http.retrofit(appStorage.getBackBaseUrl()) ) @Provides @ViewModelScoped fun provideGetSomeUseCase( repo: Repository, @ErrorHandler errorHandler: ErrorHandler ) = CheckUsedAddressUseCase(repo, errorHandler) @Provides @Singleton fun provideRepository( apiSevice: Apiservice ): Repository = RepositoryImpl(apiSevice)
@provides 와 @Binds 차이
외부적으로 기능적 차이를 보이지 않지만 사용법에 차이에서 비록한 차이가 존재한다.
1. @Binds / @povides 를 통한 주입 방법 정의 차이
@Module @InstallIn(SingletonComponent::class) abstract class RepositoryModule { @Binds @Singleton abstract fun bindRepository( repository: RepositoryImpl ): Repository
@Module @InstallIn(SingletonComponent::class) object RepositoryModule { @Provides @Singleton fun provideRepository( apiSevice: ApiService ): Repository = RepositoryImpl(apiSevice)
2. 객체 주입시 사용 방법의 차이
- @binds 의 경우 @Inject constructor 를 붙여줌으로써 해당 부분에서의 의존성 주입을 명시해주고 @provids 의 경우 그렇지 않고 모듈에서 찾아 주입해주게된다.
이런 제약으로 인해 @binds 는 서드파티 라이브러리에 대한 의존성 주입이 불가하기에 해당 경우엔 @provids 를 사용할 수 밖에 없다.
또 아래와 같이 usecaseModule 의 필요성 유무를 결정 짓기도하다. usecase 에서 인터페이스인 Repo 를 의존할 경우 @provids 의 경우 @Inject 키워드를 붙이기 않기때문에 모듈을 반드시 필요로 하지만 @binds 의 경우 @Inject 를 통해 usecase 모듈을 생성을 하지 않아도 된다.
그렇다면 @Provids 로 주입 객체를 정의하고 @Inject constructor 를 붙여준다면 usecaseModule 없이 동작할 수 있을까?
실험결과 이것 또한 가능 했다.
class GetSomeUseCase @Inject constructor( private val Repository: Repository, @ErrorHandler private val errorHandler: ErrorHandler ) : BaseUseCase() { fun execute() = Repository.getSomeUseCase() .toNetResult(errorHandler) }
(@binds 를 통한 객체 생성후 주입의 경우 usecaseModule 불필요)
@Provides @ViewModelScoped fun provideGetSomeUseCase( repo: Repository, @ErrorHandler errorHandler: ErrorHandler ) = GetSomeUseCase(repo, errorHandler) class GetSomeUseCase( private val Repository: Repository, private val errorHandler: ErrorHandler ) : BaseUseCase() {
(@provids 의 경우 @Inject Constutor 없을 경우 usecaseModule 필요)
'Android & Kotlin' 카테고리의 다른 글
Serialization 라이브러리 마이그레이션 과정(Gson -> Kotlinx-Serialization) (1) 2023.12.23 직렬화 라이브러리 마이그레이션 이유(Gson 에서 Kotlinx-Serialization) (1) 2023.12.22 DialogFragment 오류 정리 (Radius , 크기 지정) (0) 2022.11.28 By 키워드를 이용한 Shared Preference (0) 2022.11.18 Android 13 알아보기 (Target SDK 33 으로 변경) (0) 2022.11.11