π‘ InversifyJS framework to manage dependencies elegantly.
In 2015, Remo H. Jansen gave birth to InversifyJS.
A powerful and lightweight inversion of control (IoC) container for JavaScript & Node.js apps powered by TypeScript.
Today, we thank our founding father for his work, but we're not going to ask for permission to create the ultimate JavaScript dependency system on par with Angular's or NestJS's injectors from a fork of Inversify.
π‘ Welcome to Inversiland, the dependency system you've always dreamed of.
Let's compare the most popular JavaScript dependency systems.
Angular's injector allows us to relate the dependencies of one module to those of another through its import/export API.
// (Angular) common.module.ts
import { NgModule } from "@angular/core";
import { Logger } from "./logger";
@NgModule({
declarations: [Logger],
exports: [Logger],
})
export class CommonModule {}
// (Angular) cats.module.ts
import { NgModule } from "@angular/core";
import { CommonModule } from "./common.module";
import { CatsController } from "./cats.controller";
import { CatsService } from "./cats.service";
@NgModule({
imports: [CommonModule],
declarations: [CatsController, CatsService],
})
export class CatsModule {}
// (Angular) app.module.ts
import { NgModule } from "@angular/core";
import { CatsModule } from "./cats/cats.module";
@NgModule({
imports: [CatsModule],
})
export class AppModule {}
The NestJS injector also features an import/export API between modules to share dependencies.
// (NestJS) common.module.ts
import { Module } from "@nestjs/common";
import { Logger } from "./logger";
@Module({
providers: [Logger],
exports: [Logger],
})
export class CommonModule {}
// (NestJS) cats.module.ts
import { Module } from "@nestjs/common";
import { CommonModule } from "./common.module";
import { CatsController } from "./cats.controller";
import { CatsService } from "./cats.service";
@Module({
imports: [CommonModule],
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}
// (NestJS) app.module.ts
import { Module } from "@nestjs/common";
import { CatsModule } from "./cats/cats.module";
@Module({
imports: [CatsModule],
})
export class AppModule {}
Compared to modern dependency system APIs, Inversify has a number of disadvantages:
- β Your have to create all the containers separately to scope the dependencies into modules (to build a hierarchical dependency system).
- β How do you plan to relate dependencies between containers without an import/export API?
- β There is no single entry point to initialize all the containers. They are initialized at the time the files that declare them are imported.
// (Inversify) globalContainer.ts
const globalContainer = new Container();
// Global bindings here
export globalContainer
// (Inversify) commonContainer.ts
import { globalContainer } from "./globalContainer";
import { Logger } from "./Logger";
const commonContainer = globalContainer.createChild();
commonContainer.bind(Logger).toSelf().inSingletonScope();
export commonContainer;
// (Inversify) catsContainer.ts
import { globalContainer } from "./globalContainer";
import { CatsController } from "./CatsController";
import { CatsService } from "./CatsService";
const catsContainer = globalContainer.createChild();
// πΏ We can't import a subset of bindings from commonContainer
catsContainer.bind(CatsController).toSelf().inSingletonScope();
catsContainer.bind(CatsService).toSelf().inSingletonScope();
export catsContainer;
Inversiland is a framework built on top of Inversify with a clear objective: to offer an API on par with the most cutting-edge hierarchical dependency systems.
// (Inversiland) CommonModule.ts
import { module } from "inversiland";
import { Logger } from "./Logger";
@module({
providers: [Logger],
exports: [Logger],
})
export class CommonModule {}
// (Inversiland) CatsModule.ts
import { module } from "inversiland";
import { CommonModule } from "./CommonModule";
import { CatsController } from "./CatsController";
import { CatsService } from "./CatsService";
@module({
imports: [CommonModule],
providers: [CatsService, CatsController],
})
export class CatsModule {}
// (Inversiland) AppModule.ts
import { module } from "inversiland";
import { CatsModule } from "./CatsModule";
@module({
imports: [CatsModule],
})
export class AppModule {}
Follow the official guide to start using Inversiland.
Don't start your Inversiland projects from scratch, choose a well-configured template.
To keep this open source project alive, community support is needed.
- β Star the repository and share it with your coworkers.
- π² Become a sponsor so we will invest more time improving the product.
Become a sponsor of Inversiland through any platform to appear in this section.
The Inversiland source code is made available under the MIT license.
Some of the dependencies are licensed differently, with the BSD license, for example.