kotlin
144 lines · 3 tabs
Alex Chen
Jan 2026
3 tabs
package com.example.myapp
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Application initialization
}
}
package com.example.myapp.di
import com.example.myapp.data.repository.*
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
@Binds
@Singleton
abstract fun bindPostRepository(
impl: PostRepositoryImpl
): PostRepository
@Binds
@Singleton
abstract fun bindUserRepository(
impl: UserRepositoryImpl
): UserRepository
}
@Module
@InstallIn(SingletonComponent::class)
object DataModule {
@Provides
@Singleton
fun provideDatabase(
@ApplicationContext context: Context
): AppDatabase = AppDatabase.getDatabase(context)
@Provides
@Singleton
fun providePostDao(database: AppDatabase): PostDao =
database.postDao()
@Provides
@Singleton
fun provideCommentDao(database: AppDatabase): CommentDao =
database.commentDao()
}
package com.example.myapp.data.repository
import com.example.myapp.data.local.PostDao
import com.example.myapp.data.remote.ApiService
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import javax.inject.Inject
import javax.inject.Singleton
interface PostRepository {
suspend fun fetchPosts(): Result<List<Post>>
fun observePosts(): Flow<List<Post>>
suspend fun getPost(id: Int): Result<Post>
suspend fun createPost(post: Post): Result<Post>
}
@Singleton
class PostRepositoryImpl @Inject constructor(
private val apiService: ApiService,
private val postDao: PostDao,
private val mapper: PostMapper
) : PostRepository {
override suspend fun fetchPosts(): Result<List<Post>> = try {
val response = apiService.getPosts()
val posts = response.posts
// Cache to database
postDao.insertAll(posts.map { mapper.toEntity(it) })
Result.success(posts)
} catch (e: Exception) {
// Return cached data on error
val cachedPosts = postDao.getAllPosts().map { mapper.fromEntity(it) }
if (cachedPosts.isNotEmpty()) {
Result.success(cachedPosts)
} else {
Result.failure(e)
}
}
override fun observePosts(): Flow<List<Post>> =
postDao.observePosts()
.map { entities -> entities.map { mapper.fromEntity(it) } }
override suspend fun getPost(id: Int): Result<Post> = try {
val response = apiService.getPost(id)
Result.success(response.post)
} catch (e: Exception) {
postDao.getPost(id)?.let {
Result.success(mapper.fromEntity(it))
} ?: Result.failure(e)
}
override suspend fun createPost(post: Post): Result<Post> = try {
val request = CreatePostRequest(
title = post.title,
body = post.body
)
val response = apiService.createPost(request)
postDao.insert(mapper.toEntity(response.post))
Result.success(response.post)
} catch (e: Exception) {
Result.failure(e)
}
}
class PostMapper @Inject constructor() {
fun toEntity(post: Post): PostEntity = PostEntity(
id = post.id,
title = post.title,
body = post.body,
authorId = post.authorId,
createdAt = post.createdAt,
likesCount = post.likesCount
)
fun fromEntity(entity: PostEntity): Post = Post(
id = entity.id,
title = entity.title,
body = entity.body,
authorId = entity.authorId,
createdAt = entity.createdAt,
likesCount = entity.likesCount
)
}
3 files · kotlin
Explain with highlit
Hilt simplifies dependency injection in Android with compile-time code generation. I annotate Application class with @HiltAndroidApp and activities/fragments with @AndroidEntryPoint. Modules marked with @Module and @InstallIn define how to provide dependencies. @Provides methods in modules create instances, while @Binds connects interfaces to implementations. @Singleton ensures single instance app-wide. @ViewModelInject or @HiltViewModel injects ViewModels. Hilt handles scopes automatically—Activity, Fragment, View, ViewModel. Field injection uses @Inject on properties. Constructor injection is preferred for testability. Hilt integrates with Jetpack components and reduces boilerplate compared to Dagger.
Related snips
kotlin
package com.example.myapp.ui
import androidx.lifecycle.*
import kotlinx.coroutines.launch
class UserViewModel(
LiveData transformations and mediators
kotlin
android
livedata
by Alex Chen
1 tab
php
<?php
namespace App\Providers;
use App\Contracts\PaymentGateway;
use App\Services\StripePaymentGateway;
Laravel service container and dependency injection
laravel
dependency-injection
service-container
by Carlos Mendez
2 tabs
kotlin
package com.example.myapp.utils
import android.os.Build
import android.os.StrictMode
import android.os.Trace
import timber.log.Timber
Performance optimization and profiling
kotlin
android
performance
by Alex Chen
2 tabs
kotlin
package com.example.myapp.widget
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
import android.content.Context
App widgets for home screen
kotlin
android
widget
by Alex Chen
2 tabs
kotlin
package com.example.myapp.data.repository
import com.example.myapp.data.local.PostDao
import com.example.myapp.data.local.PostEntity
import com.example.myapp.data.remote.ApiService
import com.example.myapp.models.Post
Unit testing with JUnit and MockK
kotlin
android
testing
by Alex Chen
2 tabs
kotlin
package com.example.myapp.utils
import android.app.NotificationChannel
import android.app.NotificationChannelGroup
import android.app.NotificationManager
import android.app.PendingIntent
Notification channels and categories
kotlin
android
notifications
by Alex Chen
1 tab
Share this code
Here's the card — post it anywhere.