Skip to content

Commit 6e41375

Browse files
Merge pull request #186 from DrSammyD/master
Fix autoinject to allow abstract classes
2 parents ea680da + 1b735f8 commit 6e41375

File tree

3 files changed

+28
-20
lines changed

3 files changed

+28
-20
lines changed

src/injection.ts

+17-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
import { metadata } from 'aurelia-metadata';
22
import { _emptyParameters } from './container';
3-
import { DependencyCtor, Args, Impl } from './types';
3+
import { Args, Impl, DependencyCtor } from './types';
4+
5+
// tslint:disable-next-line:ban-types
6+
export type Injectable = Function & { inject?: any[] | (() => any[]) };
7+
8+
function isInjectable(potentialTarget: any): potentialTarget is Injectable {
9+
return !!potentialTarget;
10+
}
411

512
/**
613
* Decorator: Directs the TypeScript transpiler to write-out type metadata for
714
* the decorated class.
815
*/
9-
export function autoinject(
10-
potentialTarget?: DependencyCtor<any, any, any>
11-
): any {
12-
const deco = (target: DependencyCtor<any, any, any> & { inject?: any }) => {
16+
export function autoinject<TPotential>(
17+
potentialTarget?: TPotential
18+
): TPotential extends Injectable ? void : (target: Injectable) => void {
19+
const deco = (target: Injectable): void => {
1320
if (!target.hasOwnProperty('inject')) {
1421
target.inject = (
15-
(metadata.getOwn(metadata.paramTypes, target) as Array<any>) ||
22+
(metadata.getOwn(metadata.paramTypes, target) as any[]) ||
1623
_emptyParameters
1724
).slice();
1825
if (target.inject && target.inject.length > 0) {
@@ -25,10 +32,11 @@ export function autoinject(
2532
}
2633
}
2734
};
28-
29-
return potentialTarget ? deco(potentialTarget) : deco;
35+
if (isInjectable(potentialTarget)) {
36+
return deco(potentialTarget) as TPotential extends Injectable ? void : (target: Injectable) => void;
37+
}
38+
return deco as TPotential extends Injectable ? void : (target: Injectable) => void;
3039
}
31-
3240
/**
3341
* Decorator: Specifies the dependencies that should be injected by the DI Container into the decorated class/function.
3442
*/

test/injection.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ describe('injection', () => {
172172

173173
describe('inheritance', () => {
174174
@autoinject()
175-
class ParentApp {
175+
abstract class ParentApp {
176176
constructor(public logger: Logger) {
177177
this.logger = logger;
178178
}

test/resolver.spec.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ describe('resolver', () => {
7878

7979
class Logger extends LoggerBase { }
8080

81-
@autoinject()
81+
@autoinject
8282
class App {
8383
constructor(@all(LoggerBase) public loggers) {
8484
this.loggers = loggers;
@@ -150,7 +150,7 @@ describe('resolver', () => {
150150
class VerboseLogger { }
151151
class Logger { }
152152

153-
@autoinject()
153+
@autoinject
154154
class App {
155155
constructor(@optional() public logger: Logger) {
156156
}
@@ -241,7 +241,7 @@ describe('resolver', () => {
241241
it('checks the parent container hierarchy when checkParent is true or default using decorator', () => {
242242
class Logger { }
243243

244-
@autoinject()
244+
@autoinject
245245
class App {
246246
constructor(@optional() public logger: Logger) {
247247
}
@@ -325,7 +325,7 @@ describe('resolver', () => {
325325
it('returns null when no parent container exists using decorator', () => {
326326
class Logger { }
327327

328-
@autoinject()
328+
@autoinject
329329
class App {
330330
constructor(@parent public logger: Logger) {
331331
}
@@ -442,7 +442,7 @@ describe('resolver', () => {
442442
});
443443

444444
it('decorate to inject a new instance of a dependency', () => {
445-
@autoinject()
445+
@autoinject
446446
class App1 {
447447
constructor(@newInstance() public logger: Logger) {
448448
}
@@ -488,7 +488,7 @@ describe('resolver', () => {
488488
});
489489

490490
it('decorate to inject a new instance of a dependency, with instance dynamic dependency', () => {
491-
@autoinject()
491+
@autoinject
492492
class App1 {
493493
constructor(@newInstance(Logger, Dependency) public logger: Logger) {
494494
}
@@ -550,7 +550,7 @@ describe('resolver', () => {
550550
class SubService1 { }
551551
class SubService2 { }
552552

553-
@autoinject()
553+
@autoinject
554554
abstract class ParentApp {
555555
constructor(@lazy(Logger) public logger: () => Logger) { }
556556
}
@@ -562,7 +562,7 @@ describe('resolver', () => {
562562
}
563563
}
564564

565-
@autoinject()
565+
@autoinject
566566
class SubChildApp1 extends ChildApp {
567567
constructor(@lazy(SubService1) public subService1: () => SubService1,
568568
service: Service, @lazy(Logger) ...rest: [() => Logger]) {
@@ -582,7 +582,7 @@ describe('resolver', () => {
582582
class SubChildApp3 extends ChildApp {
583583
}
584584

585-
@autoinject()
585+
@autoinject
586586
class SubChildApp4 extends ChildApp {
587587
constructor(@lazy(Logger) logger: () => Logger,
588588
@lazy(SubService1) public subService1: () => SubService1, service: Service) {
@@ -644,7 +644,7 @@ describe('resolver', () => {
644644
}
645645
}
646646

647-
@autoinject()
647+
@autoinject
648648
class App {
649649
public service: Service & { data: string };
650650
constructor(

0 commit comments

Comments
 (0)