> For the complete documentation index, see [llms.txt](https://choubey.gitbook.io/javascript-interview-questions/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://choubey.gitbook.io/javascript-interview-questions/question-91.md).

# Question 91

### Question

Explain how to implement a simple dependency injection container.

### Answer

**Why Dependency Injection?**

* **Loose Coupling:** DI promotes loose coupling between components. Instead of classes directly creating their dependencies, they receive them as parameters. This makes code more modular, testable, and easier to maintain.
* **Reusability:** Dependencies can be swapped out easily without modifying the core logic of a class, allowing for flexibility and reuse across different parts of your application.

**Basic JavaScript DI Container**

```javascript
class DependencyInjectionContainer {
  constructor() {
    this.dependencies = {}; 
  }

  register(name, dependency) {
    this.dependencies[name] = dependency;
  }

  resolve(name) {
    return this.dependencies[name];
  }
}

// Example Usage

class Database {
  constructor() {
    console.log("Database connected"); 
  }
}

class UserService {
  constructor(database) {
    this.database = database;
  }

  getUserById(id) {
    console.log(`Fetching user with ID ${id} using database:`, this.database);
  }
}

const container = new DependencyInjectionContainer();
container.register('Database', Database); // Register the Database dependency

const userService = container.resolve('UserService'); 
userService.getUserById(1);
```

**Explanation:**

1. **`DependencyInjectionContainer` Class:** This class acts as our DI container. It has a `dependencies` object to store registered dependencies by name.
2. **`register(name, dependency)` Method:** Used to add dependencies to the container. The `name` is used to identify the dependency later, and `dependency` is the actual instance or constructor function of the class.
3. **`resolve(name)` Method:** Retrieves a registered dependency by its name. It returns the associated instance or function.
4. **Example Usage:**
   * We define a `Database` class to represent database interactions (simplified).
   * The `UserService` class depends on a `database`. Instead of creating the database directly, it takes it as a parameter in its constructor.
   * In the main part:
     * We create an instance of `DependencyInjectionContainer`.
     * We register the `Database` class with the container using `container.register('Database', Database)`.
     * We resolve the `UserService` (which depends on the `Database`), and it receives a database instance injected by the container.

**Key Points:**

* **Flexibility:** You can easily change dependencies without modifying classes that use them.
* **Testability:** It's much easier to test individual components when they receive their dependencies through injection, allowing you to control what they interact with during tests.
