From e1ba88ae81d9e312ebb32184a8d4a2f33de64b2d Mon Sep 17 00:00:00 2001 From: Dmitrijs Minajevs Date: Tue, 2 Oct 2018 16:21:30 +0300 Subject: [PATCH 1/2] Simplify dependency injection syntax in constructor with Reflect API --- .gitignore | 3 ++- package.json | 1 + src/lib/decorators.ts | 12 ++++++++++++ src/tests/decorators.spec.ts | 18 ++++++++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 097aa7e..a915e9a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ src/**/*.js* *.d.ts dist usage.js -CURRENT-CHANGELOG.txt \ No newline at end of file +CURRENT-CHANGELOG.txt +yarn.lock \ No newline at end of file diff --git a/package.json b/package.json index 0b465cb..b6e4077 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "gulp-tslint": "8.1.2", "gulp-typescript": "3.2.2", "mocha": "3.5.3", + "reflect-metadata": "^0.1.12", "tslint": "5.7.0", "tslint-microsoft-contrib": "5.0.1", "typescript": "2.5.3" diff --git a/src/lib/decorators.ts b/src/lib/decorators.ts index 9009c5e..f8ba8af 100644 --- a/src/lib/decorators.ts +++ b/src/lib/decorators.ts @@ -2,6 +2,7 @@ import { IInjectionMd, ProviderToken } from './interfaces'; import { INJECTABLE_MD_KEY, INJECTIONS_MD_KEY } from './metadata/keys'; import { IMetadataAnnotator } from './metadata/metadata-annotator.interface'; import { AnnotatorProvider } from './metadata/index'; +import 'reflect-metadata'; const MetadataAnnotator: IMetadataAnnotator = AnnotatorProvider.get(); @@ -14,6 +15,17 @@ export function Injectable(injections?: ProviderToken[]) { injections.forEach(token => injectionsMd.push(token)); MetadataAnnotator.defineMetadata(INJECTIONS_MD_KEY, injectionsMd, target); } + + const parameters = Reflect.getMetadata('design:paramtypes', target); + if (parameters && Array.isArray(parameters)) { + const injectionsMd: IInjectionMd[] = MetadataAnnotator.getMetadata(INJECTIONS_MD_KEY, target) || []; + parameters.forEach((param, index) => { + if (param['DI:injectable'] && !injectionsMd[index]) { + injectionsMd[index] = param; + } + }); + MetadataAnnotator.defineMetadata(INJECTIONS_MD_KEY, injectionsMd, target); + } }; } diff --git a/src/tests/decorators.spec.ts b/src/tests/decorators.spec.ts index a84364a..1b04328 100644 --- a/src/tests/decorators.spec.ts +++ b/src/tests/decorators.spec.ts @@ -4,6 +4,7 @@ import { Container } from '../lib/index'; import 'mocha'; import { expect } from 'chai'; import { Inject, Injectable } from '../lib/decorators'; +import { RegistrationProvider } from '../lib/interfaces'; /* tslint:disable: no-unused-expression max-classes-per-file*/ @@ -34,6 +35,23 @@ describe('Decorators', () => { expect(instanceB.a).to.be.instanceOf(A); }); + it('should inject dependency in to the constructor of a resolved class wihout @Inject keyword', () => { + + @Injectable() + class A { } + + @Injectable() + class B { + constructor(private a: A) { } + } + + container.register([A, B]); + + const instanceB = container.resolve(B); + + expect(instanceB.a).to.be.instanceOf(A); + }); + it('should throw an error when wrong token was provided not registered token', () => { @Injectable() class A {} From 08c201d2c1b91e13c6ef70af0f044b84d51ada24 Mon Sep 17 00:00:00 2001 From: Dmitrijs Minajevs Date: Tue, 2 Oct 2018 16:47:27 +0300 Subject: [PATCH 2/2] Updated documentation --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 0388f85..107666e 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,21 @@ container.register([ { token: App, useClass: App } ]); ``` +In such case it is redundant to use `Inject()` decorator, dependency will be injected automatically. +```typescript +@Injectable() +class AppService { + constructor(private http: HttpService) {} // instead of @Inject(HttpService) private http: HttpService +} + +@Injectable() +class HttpService { + +} + +container.register([HttpService, AppService]) +``` + ## Contribution Become a contributor to this project. Feel free to submit an [issue](https://github.com/thohoh/container-ioc/issues) or a pull request.