@ see Android | from Dagger2 to the Hilt to spin the dependency injection (a)
Front knowledge
The content of this article will involve the following pre/related knowledge, dear I have prepared for you, please enjoy ~
-
APT: 【 Like 】
-
Comments: “Java route” | annotations (including Kotlin)
-
Dagger 官网 : Dagger
-
Hilt official website: Hilt
-
Dagger 2: Github·Dragger
1. What is dependency injection?
In software design, we divide code into different classes based on different responsibilities. And between different congeners will be combined with each other, forming a dependent relationship. For example, in the Android application login process, LoginActivity relies on LoginViewModel, which in turn relies on UserRepository.
— quote from the developer. The android. Google. Cn/training/DE… – the Android Developers
The most direct way for the LoginActivity class to get dependent objects is to construct them inside the class, for example:
val retrofit = Retrofit.Builder()
.baseUrl("https://example.com")
.build()
.create(LoginService::class.java)
val remoteDataSource = UserRemoteDataSource(retrofit)
val localDataSource = UserLocalDataSource()
val userRepository = UserRepository(localDataSource, remoteDataSource)
loginViewModel = LoginViewModel(userRepository)
Copy the code
This method is the most common, but has many problems:
- 1. Unable to reuse code/objects: if dependent objects need to be created elsewhere in the project, duplicate code needs to be used and objects need to be created repeatedly;
- 2. Objects must be created in sequence: UserRepository must be instantiated before LoginViewModel can be instantiated;
To optimize these problems, they can be improved in two ways:
- 1. Service provision mode: fetching dependent objects from external service containers
- 2. Dependency injection: Inject dependent objects in the form of parameters
As you can see, the difference between the first and the latter two is that the location of the dependent object is inside/outside the class. If the dependent object is constructed outside the class, it is called an Inversion of Control (IoC). IoC can be considered as a design pattern, but it is not included in Design Patterns ·GoF due to its relatively late theoretical maturity.
1.2 Service Locator Pattern
Create a dependency container class that constructs and stores dependent objects. The caller actively grabs dependent objects from the external service container, for example:
Class AppContainer {private val retrofit = retrofit.builder ().baseurl ("https://example.com").build() .create(LoginService::class.java) private val remoteDataSource = UserRemoteDataSource(retrofit) private val localDataSource = UserLocalDataSource() val userRepository = UserRepository(localDataSource, remoteDataSource) }Copy the code
class MyApplication : Application() {
val appContainer = AppContainer()
}
Copy the code
val appContainer = (application as MyApplication).appContainer
loginViewModel = LoginViewModel(appContainer.userRepository)
Copy the code
1.3 Dependency Injection
We construct dependencies outside the class and inject them as parameters, such as in constructors, setter methods, so we use dependency injection all the time. The essential difference between dependency injection and the service provision pattern is that with the service provision pattern, the caller can control the timing of requests for dependent objects. In the case of dependency injection, the required objects are usually injected proactively from outside.
1.4 summary
Using dependency injection brings us the following benefits:
- Inject or configure dependencies externally so that we can reuse these components. When we need to change the implementation of a dependency, we don’t need to change a lot of code, only a small part of the code;
- 2. Mock implementations of dependencies can be injected to make code testing easier.
2. Android dependency injection framework
In the last section, we explained dependency injection, but we do use it all the time without realizing it. Manual dependency injection is simple when there is only one dependency, but becomes increasingly complex as the project grows in size.
However, dependency injection framework can make the process of dependency injection easier, which can be classified into two categories:
- 1. Dynamic scheme based on reflection
Google Guice, for example, suffers from performance loss due to the use of reflection.
- Static solutions based on compile-time annotations
Examples are Dragger(:[‘dægə]), Hilt([hɪlt]), and ButterKnife. ButterKnife can only implement dependency injection of controls, while Dragger and Hilt have wider application scenarios. Compile-time annotation-based schemes generate code linking dependencies at compile time, so reflection is not used.
2.1 Dagger
The Dagger framework was originally developed by the Square organization, while the Dagger2 and Hilt frameworks were developed and maintained by Square and Google. Named for the Directed Acyclic Graph (DAG), Dagger does not provide dependency injection per se, but annotates to make dependency injection easier.
2.2 Hilt
Hilt is actually a secondary encapsulation of Dagger2 for Android platform. Hilt is essentially a scenario for Dagger, which makes a series of rules for Android platform and greatly simplifies the use of Dagger. While in the Dagger you need to manually get the dependency graph and perform the injection, in Hilt the injection is done automatically as Hilt automatically finds the best injection locations in the Android system components.
3. Dagger2
No more learning, Dagger2 here, first arrange Hilt.
4. To summarize
-
1. Dependency injection builds dependent objects outside the class, so that the code and components of the dependency can be reused. It can also inject simulated implementation of the dependency, making the code easier to test;
-
2. Dagger does not provide dependency injection capability in essence, but uses annotations to make dependency injection easier; Hilt is a secondary wrapper for Dagger2, which essentially scenariotizes the Dagger;
The resources
- Dependency Injection – Wikipedia
- Tasting Dagger 2 on Android. By Fernando Cejas
- From Dagger to Hilt, why Is Google obsessed with dependency Injection? — Throwing objects on the line
- Dependency Injection in Android series — Android Developers
- Dagger Navigation Update for Android Studio 4.1 — Android Developers
- Dagger Traps and optimization in Kotlin Android Developers
- Custom WorkManager with Dagger — Android Developers
Creation is not easy, your “three lian” is chouchou’s biggest motivation, we will see you next time!