# Android, Hilt: Inject multiple instances of a Object to the Dependent Modules.

> If get to know something new by reading my articles, don't forget to endorse me on [LinkedIn](https://www.linkedin.com/in/rommansabbir/)

# Topic

In our **Modern Application Development**, we use ***DI*** (***Dagger/Dagger2/ Hilt***). As we follow **Depdendency Injection**, we love to inject (`@Inject`) objects as much as possible instead of creating/destroying the objects at our own.

Specially, ***we might need to inject multiple instances of same type objects to the dependent module***.

So, How do we resolve this scenarios by following ***Dependency Injection***?

Simple, by using ***Annotations***.

# What or How `@Named` Annotation works?

`@Named` to differentiate between different objects of the same type bound in the same scope.

```plaintext
    @Provides
    @Named("userId")
    fun provideUserId(): Int = DataHolder.userId

    @Provides
    @Named("profileId")
    fun provideProfileId(): Int = DataHolder.profileId
```

Without the `@Named` qualifier, the injector would not know which `Int` to bind to which variable.

* If you want to create annotations that act like `@Named`, use the `@Qualifier` annotation when creating them.
    
* If you look at `@Named`, it is itself annotated with `@Qualifier`.
    

# Let's get into the coding part

```plaintext
object DataHolder {
    @Volatile
    var userId: Int = -1

    @Volatile
    var profileId: Int = -1
}
```

We are using **In-Memory** holder to transfer data from one module to another module. `@Volatile` mark the objects to be stored in the **Main Memory** to access the updated instances by multiple ***Clients*** or ***Threads***.

*We will inject the stored objects instances to the* ***Dependent Modules*** *by using* ***DI***.

```plaintext
@Module
@InstallIn(ViewModelComponent::class)
object ViewModelComponent {
    @Provides
    @Named("userId")
    fun provideUserId(): Int = DataHolder.userId

    @Provides
    @Named("profileId")
    fun provideProfileId(): Int = DataHolder.profileId
}
```

Create a new `Object` called `ViewModelComponent` and mark the `Object` as `@Module` (That contributes to the object graph) and `@InstallIn(ViewModelComponent::class)` (That declares which component(s) the annotated class should be included in when Hilt generates the components.)

Here, we are providing the multiple values of ***Int Object*** as **User ID** and **Profile ID** to the dependent module by annotating the `Functions/APIs` with `@Provided` and `@Named`

```plaintext
@HiltViewModel
class ExampleViewModel @Inject constructor(
    @Named("userId") private val userId: Int,
    @Named("profileId") private val profileId: Int
) :
    ViewModel() {
    init {
        println("$userId, $profileId provided by Hilt")
    }
}
```

Here, the client/dependent module `ExampleViewModel` received the multiple instances of ***Int Object*** by Injecting (`@Inject`) the constructor and ***Annotating*** parameters with respective unique IDs (`userId`, `profileId`).

```plaintext
class TestFragment : Fragment() {
    companion object {
        fun newInstance(userId: Int, profileId: Int): TestFragment {
            /*Store the user id to the *DataHolder**/
            DataHolder.userId = userId
            DataHolder.profileId = profileId
            return TestFragment()
        }
    }
}
```

Finally, before creating a new instance of `Fragment` or `Activity` store the values to the `DataHolder` to provide the new values to the dependent modules by using ***Hilt***.

# Full Implementation in Kotlin

%[https://gist.github.com/rommansabbir/e14f93d37a334c2d3f778f874cbdd7dc] 

Happy Coding...
