From c4b739b6b9d67705de896d6ece42b0fc40e16c0f Mon Sep 17 00:00:00 2001 From: Serhii Sol Date: Wed, 9 Aug 2023 21:21:40 +0300 Subject: [PATCH] feat(di): provided in root injectables (#186) --- di/package-lock.json | 4 ++-- di/package.json | 2 +- di/src/container.spec.ts | 22 ++++++++++++++++------ di/src/decorators/injectable.ts | 15 ++++++++++++++- di/src/index.ts | 3 +-- di/src/root-container.ts | 3 +++ 6 files changed, 37 insertions(+), 12 deletions(-) create mode 100644 di/src/root-container.ts diff --git a/di/package-lock.json b/di/package-lock.json index 0ab0efe..0b96964 100644 --- a/di/package-lock.json +++ b/di/package-lock.json @@ -1,12 +1,12 @@ { "name": "@decorators/di", - "version": "3.0.0", + "version": "3.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@decorators/di", - "version": "3.0.0", + "version": "3.1.0", "license": "MIT", "dependencies": { "reflect-metadata": "^0.1.13" diff --git a/di/package.json b/di/package.json index 944e1f4..6289f4e 100644 --- a/di/package.json +++ b/di/package.json @@ -42,5 +42,5 @@ "test": "jest" }, "types": "lib/index.d.ts", - "version": "3.0.1" + "version": "3.1.0" } diff --git a/di/src/container.spec.ts b/di/src/container.spec.ts index d6110e2..9f37e17 100644 --- a/di/src/container.spec.ts +++ b/di/src/container.spec.ts @@ -3,6 +3,7 @@ import { Container } from './container'; import { InjectionToken } from './injection-token'; import { Injectable, Inject } from './decorators'; import { InvalidDependencyError, MissingDependencyError, RecursiveDependencyError } from './errors'; +import { RootContainer } from './root-container'; describe('Container', () => { let extraContainer: Container; @@ -111,7 +112,7 @@ describe('Container', () => { describe('ClassProvider', () => { it('registers a provider', async () => { @Injectable() - class TestInjectable {} + class TestInjectable { } container.provide([ { provide: TestInjectable, useClass: TestInjectable }, @@ -122,10 +123,10 @@ describe('Container', () => { it('replaces a provider', async () => { @Injectable() - class TestInjectable {} + class TestInjectable { } @Injectable() - class AnotherInjectable {} + class AnotherInjectable { } container.provide([ { provide: TestInjectable, useClass: TestInjectable }, @@ -251,7 +252,7 @@ describe('Container', () => { it('registers a provider for existing class', async () => { @Injectable() - class TestInjectable {} + class TestInjectable { } const token = new InjectionToken('token'); @@ -293,7 +294,7 @@ describe('Container', () => { const token = new InjectionToken('token'); @Injectable() - class TestInjectable {} + class TestInjectable { } container.provide([ { provide: token, useClass: TestInjectable, multi: true }, @@ -312,7 +313,7 @@ describe('Container', () => { const token = new InjectionToken('token'); @Injectable() - class TestInjectable {} + class TestInjectable { } container.provide([ { provide: token, useValue: 1, multi: true }, @@ -345,3 +346,12 @@ describe('Container', () => { }); }); }); + +describe('RootContainer', () => { + it('registers a provider in RootContainer', async () => { + @Injectable({ providedIn: 'root' }) + class TestInjectable { } + + expect(await RootContainer.has(TestInjectable)).toBeTruthy(); + }); +}); diff --git a/di/src/decorators/injectable.ts b/di/src/decorators/injectable.ts index 394dd3d..5be1586 100644 --- a/di/src/decorators/injectable.ts +++ b/di/src/decorators/injectable.ts @@ -1,7 +1,13 @@ import { ClassConstructor } from '../types'; import { DEP_IDS_METADATA } from '../constants'; -export function Injectable() { +import { RootContainer } from '../root-container'; + +interface InjectableOptions { + providedIn?: 'root'; +} + +export function Injectable(options?: InjectableOptions) { return (target: ClassConstructor) => { const params = Reflect.getMetadata('design:paramtypes', target) ?? []; const ids = Reflect.getMetadata(DEP_IDS_METADATA, target) ?? []; @@ -13,5 +19,12 @@ export function Injectable() { }); Reflect.defineMetadata(DEP_IDS_METADATA, verifiedIds, target); + + if (options?.providedIn === 'root') { + RootContainer.provide([{ + provide: target, + useClass: target, + }]); + } }; } diff --git a/di/src/index.ts b/di/src/index.ts index 717b518..7e3d1d0 100644 --- a/di/src/index.ts +++ b/di/src/index.ts @@ -1,7 +1,6 @@ import 'reflect-metadata'; -import { Container } from './container'; -export const RootContainer = new Container(); +export { RootContainer } from './root-container'; export { Container } from './container'; export { Injectable, Inject, Optional } from './decorators'; export { InjectionToken } from './injection-token'; diff --git a/di/src/root-container.ts b/di/src/root-container.ts new file mode 100644 index 0000000..93cb0f7 --- /dev/null +++ b/di/src/root-container.ts @@ -0,0 +1,3 @@ +import { Container } from './container'; + +export const RootContainer = new Container();