Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hilt in non-android module clean architecture setup

I have a multi modular android app setup which consists of a Data, Domain and Presentation module. The Domain module is java-only. I know it's possible to support hilt in non-android modules by adding:

Domain build.gradle

implementation "com.google.dagger:hilt-core:$hilt_version"
kapt "com.google.dagger:hilt-compiler:$hilt_version"

The domain module provides implementations of UseCase classes that should be injected in the ViewModels which live in the Presentation (app)module.

Domain Module:

@Module
@InstallIn(SingletonComponent::class)
//   @InstallIn(ViewModelComponent::class)
object UseCaseModule {

    @Provides
    //    @ViewModelScoped
    fun provideGetMovieDetailsUseCase(
        movieRepository: MovieRepository
    ): GetMovieDetailsUseCase {
        return GetMovieDetailsUseCaseImpl(movieRepository)
    }
}

Presentation Module:

@HiltViewModel
class MovieDetailViewModel @Inject constructor(
    private val getMovieDetailsUseCase: GetMovieDetailsUseCase
) : ViewModel() {
    ...
}

Because of the nature of the java-only module, I can't use the @InstallIn(ViewModelComponent::class) annotation. Instead I have to install the dependency in the SingletonComponent::class. Which is also done in an awnser here

My Question

Is this approach 'best practice'? Or is it better to make the library an Android library so that I can scope the dependency to the ViewModel? I would prefer to keep it a java-only library.

like image 337
Tim Avatar asked Jan 25 '23 08:01

Tim


1 Answers

A common practice I'm aware of is moving dependency configuration for all modules to the app module (since the use of Hilt is at the framework level). You can then use the java inject library to inject dependencies in the pure java libraries (e.g domain layer).

So in your app build.gradle file, you'll have:

// hilt dependency
implementation "com.google.dagger:hilt-android:2.28-alpha"
implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha02'
kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha02'
kapt "com.google.dagger:hilt-android-compiler:2.28-alpha"

and in your domain build.gradle file, you'll have:

implementation "javax.inject:javax.inject:$javaInjectVersion"

In summary, the file where you "wire up" the domain module dependencies should be moved to the app module.

Here's a project that demonstrates the idea.

like image 67
Tobi Daada Avatar answered Jan 29 '23 23:01

Tobi Daada