Dagger y los componentes de la arquitectura de Android con Kotlin | Por Nigel Chomba | Marzo de 2022
Como todos sabemos, la inyección de dependencia (DI) es una técnica muy utilizada en programación, muy adecuada para el desarrollo de Android y muy concisa utilizando el lenguaje de programación Kotlin.
Siguiendo los principios de DI, puede sentar las bases para una buena arquitectura de aplicaciones.
Los beneficios y ventajas de la inyección de dependencia son:
- Reutilización de código.
- Fácil de refactorizar.
- Fácil de probar.
Demostraré esto a continuación usando Kotlin y obteniendo datos de una API REST
- Tengo mi clase de datos userSission como respuesta de la API REST
data class SessionBase(
@SerializedName("session") var session: Session? = null
)
2. Servicio de actualización
interface APIService {@Headers("Accept: application/json", "Content-Type: application/json")
@POST("api3/login")
fun login(@Query("email") email: String, @Query("password") password: String): Call
}
3. Adaptar el cliente con interceptores para autenticar mis llamadas API REST
object RetrofitClient {private val client = OkHttpClient.Builder()
.addInterceptor(OAuthInterceptor("Bearer", API_KEY))
.build()
private val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build()
val aPIService: APIService = retrofit.create(APIService::class.java)
}
4. Interceptor de autenticación
class OAuthInterceptor(private val tokenType: String, private val acceessToken: String): Interceptor {override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
var request = chain.request()
request = request.newBuilder().header("Authorization", "$tokenType $acceessToken").build()
return chain.proceed(request)
}
}
5. Configuré mi módulo de aplicación para proporcionar el objeto de contexto
@Module
class ApplicationModule {@Provides
fun providesApplication(): Application {
return Application()
}
}
6. Configuro mi AppComponent para agregar LoginViewModel y agrego mi LoginActivity al diagrama para permitir la inyección de campo de mi viewModel
@Component(modules = [ApplicationModule::class])
interface AppComponent {fun loginViewModel(): LoginViewModel
fun inject(activity: LoginActivity)
}
7. Mi clase LoginRepository
class LoginRepository {private val mService: APIService by lazy {
RetrofitClient.APIService
}
fun login(email: String, password: String): Call {
return mService.login(email = email, password = password)
}
}
8. Mi clase LoginViewModel inyecta mi constructor viewModel
class LoginViewModel @Inject constructor() : ViewModel() {private var loginRepository: LoginRepository = LoginRepository()
private val session = MutableLiveData>()
fun login(email: String, password: String): LiveData> {
loginRepository.login(email, password).enqueue(object : Callback {
override fun onResponse(call: Call, response: Response) {
session.value = response
}
override fun onFailure(call: Call, t: Throwable) {
}
})
return session
}
}
9. Finalmente, en mi LoginViewModel puedo inyectar campos en la actividad de inicio de sesión y
class LoginActivity : AppCompatActivity() {private lateinit var binding: ActivityLoginBinding
@Inject lateinit var loginViewModel: LoginViewModel
override fun onCreate(savedInstanceState: Bundle?) {
DaggerAppComponent.create().inject(this)
super.onCreate(savedInstanceState)
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
}
}
Eso es todo al final, puede seguir esta sección para todos sus modelos de vista y actividades.