A powerful and lightweight inversion of control container for JavaScript and Node.js apps powered by TypeScript.
npx @tessl/cli install tessl/npm-inversify@7.9.00
# InversifyJS
1
2
InversifyJS is a powerful and lightweight inversion of control (IoC) container for JavaScript and Node.js applications powered by TypeScript. It enables developers to write code that adheres to SOLID principles and encourages the use of best object-oriented programming and IoC practices. The library provides dependency injection, lifecycle management, and conditional binding features with zero runtime dependencies beyond reflection metadata.
3
4
## Package Information
5
6
- **Package Name**: inversify
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install inversify reflect-metadata`
10
- **Repository**: https://github.com/inversify/InversifyJS
11
- **Documentation**: https://inversify.io
12
13
## Core Imports
14
15
```typescript
16
import { Container, injectable, inject } from "inversify";
17
import "reflect-metadata";
18
```
19
20
For CommonJS:
21
22
```javascript
23
const { Container, injectable, inject } = require("inversify");
24
require("reflect-metadata");
25
```
26
27
## Basic Usage
28
29
```typescript
30
import { Container, injectable, inject } from "inversify";
31
import "reflect-metadata";
32
33
// Define interfaces
34
interface Warrior {
35
fight(): string;
36
}
37
38
interface Weapon {
39
hit(): string;
40
}
41
42
// Implement classes with decorators
43
@injectable()
44
class Katana implements Weapon {
45
hit() {
46
return "cut!";
47
}
48
}
49
50
@injectable()
51
class Ninja implements Warrior {
52
private _weapon: Weapon;
53
54
constructor(@inject("Weapon") weapon: Weapon) {
55
this._weapon = weapon;
56
}
57
58
fight() {
59
return this._weapon.hit();
60
}
61
}
62
63
// Configure container and resolve dependencies
64
const container = new Container();
65
container.bind<Warrior>("Warrior").to(Ninja);
66
container.bind<Weapon>("Weapon").to(Katana);
67
68
const warrior = container.get<Warrior>("Warrior");
69
console.log(warrior.fight()); // "cut!"
70
```
71
72
## Architecture
73
74
InversifyJS is built around several key architectural components:
75
76
- **Container**: The central IoC container that manages service registration, resolution, and lifecycle
77
- **Binding System**: Fluent API for configuring how services are created and injected
78
- **Decorator System**: TypeScript decorators for marking injectable classes and injection points
79
- **Resolution Engine**: Handles dependency graph resolution, circular dependency detection, and service instantiation
80
- **Conditional Binding**: Support for context-aware dependency resolution based on tags, names, and ancestry
81
- **Lifecycle Management**: Hooks for construction/destruction events and scope management (singleton, transient, request)
82
83
## Capabilities
84
85
### Container Management
86
87
Core container functionality for service registration, binding configuration, and dependency resolution. The Container class provides the primary interface for IoC operations.
88
89
```typescript { .api }
90
class Container {
91
bind<T>(serviceIdentifier: ServiceIdentifier<T>): BindInFluentSyntax<T>;
92
rebind<T>(serviceIdentifier: ServiceIdentifier<T>): BindInFluentSyntax<T>;
93
unbind(serviceIdentifier: ServiceIdentifier): void;
94
isBound(serviceIdentifier: ServiceIdentifier): boolean;
95
get<T>(serviceIdentifier: ServiceIdentifier<T>): T;
96
getAll<T>(serviceIdentifier: ServiceIdentifier<T>): T[];
97
load(...modules: ContainerModule[]): void;
98
unload(...modules: ContainerModule[]): void;
99
}
100
```
101
102
[Container Management](./container.md)
103
104
### Decorators and Annotations
105
106
Core decorator functions for marking classes as injectable and specifying dependency injection points. These decorators work with TypeScript's metadata reflection system.
107
108
```typescript { .api }
109
function injectable<T>(target: Newable<T>): void;
110
function inject(serviceIdentifier: ServiceIdentifier): (target: any, targetKey: string, index: number) => void;
111
function multiInject(serviceIdentifier: ServiceIdentifier): (target: any, targetKey: string, index: number) => void;
112
function named(name: string): (target: any, targetKey: string, index: number) => void;
113
function tagged(key: string, value: any): (target: any, targetKey: string, index: number) => void;
114
function optional(): (target: any, targetKey: string, index: number) => void;
115
```
116
117
[Decorators and Annotations](./decorators.md)
118
119
### Binding Configuration
120
121
Fluent API for configuring service bindings including target specification, scope management, and conditional resolution. Supports various binding patterns from simple class binding to complex factory configurations.
122
123
```typescript { .api }
124
interface BindToFluentSyntax<T> {
125
to(constructor: Newable<T>): BindInWhenOnFluentSyntax<T>;
126
toSelf(): BindInWhenOnFluentSyntax<T>;
127
toConstantValue(value: T): BindWhenOnFluentSyntax<T>;
128
toDynamicValue(func: (context: ResolutionContext) => T): BindInWhenOnFluentSyntax<T>;
129
toFactory<T2>(factory: Factory<T2>): BindWhenOnFluentSyntax<T>;
130
toProvider<T2>(provider: Provider<T2>): BindWhenOnFluentSyntax<T>;
131
}
132
133
interface BindInWhenOnFluentSyntax<T> {
134
inSingletonScope(): BindWhenOnFluentSyntax<T>;
135
inTransientScope(): BindWhenOnFluentSyntax<T>;
136
inRequestScope(): BindWhenOnFluentSyntax<T>;
137
}
138
```
139
140
[Binding Configuration](./binding.md)
141
142
### Conditional Resolution
143
144
Advanced features for context-aware dependency resolution including named bindings, tagged bindings, and ancestry-based conditional resolution. Enables sophisticated dependency injection scenarios.
145
146
```typescript { .api }
147
interface BindWhenFluentSyntax<T> {
148
when(constraint: (request: ResolutionContext) => boolean): BindOnFluentSyntax<T>;
149
whenTargetNamed(name: string): BindOnFluentSyntax<T>;
150
whenTargetTagged(tag: string, value: any): BindOnFluentSyntax<T>;
151
whenInjectedInto(parent: Newable<any>): BindOnFluentSyntax<T>;
152
whenParentNamed(name: string): BindOnFluentSyntax<T>;
153
whenParentTagged(tag: string, value: any): BindOnFluentSyntax<T>;
154
whenAnyAncestorIs(ancestor: Newable<any>): BindOnFluentSyntax<T>;
155
whenNoAncestorIs(ancestor: Newable<any>): BindOnFluentSyntax<T>;
156
}
157
```
158
159
[Conditional Resolution](./conditional.md)
160
161
### Lifecycle Management
162
163
Lifecycle hooks and scope management for controlling service instantiation, activation, deactivation, and destruction. Supports singleton, transient, and request-scoped lifetimes.
164
165
```typescript { .api }
166
function postConstruct(target: any, propertyKey: string): void;
167
function preDestroy(target: any, propertyKey: string): void;
168
169
interface BindOnFluentSyntax<T> {
170
onActivation(handler: (context: ResolutionContext, injectable: T) => T): BindInFluentSyntax<T>;
171
onDeactivation(handler: (injectable: T) => void): BindInFluentSyntax<T>;
172
}
173
```
174
175
[Lifecycle Management](./lifecycle.md)
176
177
### Module System
178
179
Container module system for organizing and packaging related service bindings. Enables modular IoC configuration and supports dynamic loading/unloading of service groups.
180
181
```typescript { .api }
182
class ContainerModule {
183
constructor(
184
registry: (bind: BindFunction, unbind: UnbindFunction, isBound: IsBoundFunction, rebind: RebindFunction) => void
185
);
186
}
187
188
interface ContainerModuleLoadOptions {
189
skipDeactivation?: boolean;
190
}
191
```
192
193
[Module System](./modules.md)
194
195
## Types
196
197
### Core Service Types
198
199
```typescript { .api }
200
type ServiceIdentifier<T = {}> = string | symbol | Newable<T> | Abstract<T>;
201
type Newable<T = {}> = new (...args: any[]) => T;
202
interface LazyServiceIdentifier<T = {}> {
203
unwrap(): ServiceIdentifier<T>;
204
}
205
```
206
207
### Factory and Provider Types
208
209
```typescript { .api }
210
type Factory<T> = () => T;
211
type Provider<T> = () => Promise<T>;
212
type DynamicValueBuilder<T> = (context: ResolutionContext) => T;
213
```
214
215
### Binding Scope Types
216
217
```typescript { .api }
218
const bindingScopeValues: {
219
Singleton: "Singleton";
220
Transient: "Transient";
221
Request: "Request";
222
};
223
224
const bindingTypeValues: {
225
Instance: "Instance";
226
Value: "Value";
227
Constructor: "Constructor";
228
Factory: "Factory";
229
Provider: "Provider";
230
Function: "Function";
231
DynamicValue: "DynamicValue";
232
};
233
234
type BindingScope = keyof typeof bindingScopeValues;
235
```
236
237
### Resolution Context Types
238
239
```typescript { .api }
240
interface ResolutionContext {
241
container: Container;
242
currentRequest: Request;
243
plan: Plan;
244
addPlan(plan: Plan): void;
245
}
246
247
interface GetOptions {
248
skipBaseClassChecks?: boolean;
249
}
250
251
interface GetAllOptions {
252
skipBaseClassChecks?: boolean;
253
}
254
255
interface OptionalGetOptions extends GetOptions {
256
defaultValue?: any;
257
}
258
259
interface GetOptionsTagConstraint {
260
key: string;
261
value: any;
262
}
263
264
interface MultiInjectOptions {
265
skipDeactivation?: boolean;
266
ignoreMissingBindings?: boolean;
267
}
268
```