Inversion of Control Basics
Understand why and when to invert dependencies.
Inversion of Control Basics is a free TypeScript Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Hard-Coded Dependencies
When a class creates its own collaborators with new, it is tightly coupled to those concrete types. This makes the class hard to reconfigure and hard to test.
A Tightly Coupled Example
Here the service builds its own logger. There is no way to substitute a different logger without editing the class.
class ConsoleLogger { log(m: string) { console.log(m); } }
class OrderService {
private logger = new ConsoleLogger(); // hard-coded
place() { this.logger.log("order placed"); }
}
new OrderService().place();What Is Inversion of Control?
Inversion of Control (IoC) flips who decides on dependencies. Instead of a class creating them, something outside provides them. The class declares what it needs and receives it.
Dependency Injection
Dependency Injection (DI) is the common way to achieve IoC: pass collaborators in rather than constructing them internally. The caller controls which implementation is used.
The Injected Version
Now the logger is supplied from outside. The service no longer knows or cares which concrete logger it received.
class OrderService {
constructor(private logger: { log(m: string): void }) {}
place() { this.logger.log("order placed"); }
}
new OrderService(new ConsoleLogger()).place();Why IoC Improves Testability
Because dependencies come from outside, tests can pass in fakes or spies. You can verify behavior without real I/O, databases, or network calls.
const calls: string[] = [];
const fakeLogger = { log: (m: string) => calls.push(m) };
new OrderService(fakeLogger).place();
console.log(calls); // ["order placed"]Depend on Abstractions
IoC works best when classes depend on an interface rather than a concrete class. Any implementation that satisfies the interface can be injected.
interface Logger { log(m: string): void; }
class OrderService {
constructor(private logger: Logger) {}
}Constructor Injection
Constructor injection passes dependencies as constructor parameters. They are available immediately and can be marked readonly, making them clear and required.
class OrderService {
constructor(private readonly logger: Logger) {}
}Property Injection
Property injection sets a dependency on a public or settable property after construction. It is more flexible but allows the object to exist temporarily without the dependency.
class OrderService {
logger!: Logger; // set after construction
place() { this.logger.log("placed"); }
}
const s = new OrderService();
s.logger = new ConsoleLogger();Choosing a Style
Prefer constructor injection for required dependencies, because the object is never in a half-built state. Use property injection for optional collaborators or to break construction cycles.
IoC Containers Preview
For large apps, wiring dependencies by hand grows tedious. An IoC container automates creating and supplying dependencies, which the next lessons explore with InversifyJS.
Quick Check
Quick check on this lesson.
Recap
Inversion of Control moves dependency creation outside the class; dependency injection supplies them in. Depend on interfaces, prefer constructor injection for required deps, and gain easy testing by injecting fakes.
Frequently asked questions
Is the “Inversion of Control Basics” lesson free?
Yes — the full text of “Inversion of Control Basics” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “Inversion of Control Basics”?
Understand why and when to invert dependencies. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Inversion of Control Basics” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Inversion of Control Basics
- Constructor Injection
- DI Containers with InversifyJS
- Type-Safe Service Tokens