Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

feat: inject non-annotated tokens as values #45

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion example/coffee/electric_heater.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Provide} from 'di';
import {Inject, Provide} from 'di';

import {Heater} from './heater';

@Inject()
@Provide(Heater)
export class ElectricHeater {
constructor() {}
Expand Down
3 changes: 2 additions & 1 deletion example/coffee/mock_heater.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import {Provide} from 'di';
import {Inject, Provide} from 'di';

import {Heater} from './heater';

@Inject()
@Provide(Heater)
export class MockHeater {
on() {}
Expand Down
2 changes: 2 additions & 0 deletions example/kitchen-di/electricity.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
import {Inject} from 'di';

@Inject
export class Electricity {}
4 changes: 3 additions & 1 deletion example/kitchen-di/mock_heater.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {Provide} from 'di';
import {Inject, Provide} from 'di';
import {Heater} from './coffee_maker/heater';


@Inject
@Provide(Heater)
export class MockHeater {
constructor() {}
Expand Down
3 changes: 3 additions & 0 deletions example/kitchen-di/skillet.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import {Inject} from 'di';


@Inject
export class Skillet {
constructor() {}

Expand Down
18 changes: 18 additions & 0 deletions src/annotations.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ function hasAnnotation(fn, annotationClass) {
}


function hasParameterAnnotation(fn, AnnotationClass) {
if (!fn.parameters || fn.parameters.length === 0) {
return false;
}

for (var parameterAnnotations of fn.parameters) {
for (var annotation of parameterAnnotations) {
if (annotation instanceof AnnotationClass) {
return true;
}
}
}

return false;
}


// Read annotations on a function or class and collect "interesting" metadata:
function readAnnotations(fn) {
var collectedAnnotations = {
Expand Down Expand Up @@ -143,6 +160,7 @@ function readAnnotations(fn) {
export {
annotate,
hasAnnotation,
hasParameterAnnotation,
readAnnotations,

SuperConstructor,
Expand Down
19 changes: 14 additions & 5 deletions src/injector.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import {
annotate,
readAnnotations,
hasAnnotation,
hasParameterAnnotation,
Provide as ProvideAnnotation,
Inject as InjectAnnotation,
TransientScope as TransientScopeAnnotation
} from './annotations';
import {isFunction, toString} from './util';
import {isFunction, isObject, toString} from './util';
import {profileInjector} from './profiler';
import {createProviderFromFnOrClass} from './providers';
import {createProviderFromFnOrClass, createProviderFromValue} from './providers';


function constructResolvingMessage(resolving, token) {
Expand Down Expand Up @@ -143,6 +145,7 @@ class Injector {
return args[ii + 1];
};

annotate(fn, new InjectAnnotation());
annotate(fn, new ProvideAnnotation(args[ii]));

return fn;
Expand Down Expand Up @@ -176,9 +179,15 @@ class Injector {
provider = this.providers.get(token);

// No provider defined (overriden), use the default provider (token).
if (!provider && isFunction(token) && !this._hasProviderFor(token)) {
provider = createProviderFromFnOrClass(token, readAnnotations(token));
this.providers.set(token, provider);
if (!provider && !this._hasProviderFor(token)) {
if (isFunction(token) && (hasAnnotation(token, InjectAnnotation)) || hasParameterAnnotation(token, InjectAnnotation)) {
provider = createProviderFromFnOrClass(token, readAnnotations(token));
this.providers.set(token, provider);
} else if (isFunction(token) || isObject(token)) {
// If the token is an object or a non-annotated function, we inject it as a value.
provider = createProviderFromValue(token);
this.providers.set(token, provider);
}
}

if (!provider) {
Expand Down
22 changes: 22 additions & 0 deletions src/providers.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,32 @@ class FactoryProvider {
}


// ValueProvider knows how to return values.
//
// This is a trivial provider that just always returns the same value,
// without requiring any arguments.
class ValueProvider {
constructor(value) {
this.provider = function() {};
this.params = [];
this.isPromise = false;
this._value = value;
}

create() {
return this._value;
}
}


export function createProviderFromFnOrClass(fnOrClass, annotations) {
if (isClass(fnOrClass)) {
return new ClassProvider(fnOrClass, annotations.params, annotations.provide.isPromise);
}

return new FactoryProvider(fnOrClass, annotations.params, annotations.provide.isPromise);
}

export function createProviderFromValue(value) {
return new ValueProvider(value);
}
23 changes: 23 additions & 0 deletions test/annotations.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
hasAnnotation,
hasParameterAnnotation,
readAnnotations,
Inject,
InjectLazy,
Expand Down Expand Up @@ -43,6 +44,28 @@ describe('hasAnnotation', function() {
});


describe('hasParameterAnnotation', function() {

it('should return false if no annotation', function() {
class FooAnnotation {}

function nothing() {}

expect(hasParameterAnnotation(nothing, FooAnnotation)).toBe(false);
});


it('should return if at least one parameter has specific annotation', function() {
class FooAnnotation {}
class BarType {}

function nothing(one: BarType, @FooAnnotation two: BarType) {}

expect(hasParameterAnnotation(nothing, FooAnnotation)).toBe(true);
});
});


describe('readAnnotations', function() {

it('should read @Provide', function() {
Expand Down
2 changes: 2 additions & 0 deletions test/async.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import {Injector} from '../src/injector';
class UserList {}

// An async provider.
@Inject
@ProvidePromise(UserList)
function fetchUsers() {
return Promise.resolve(new UserList);
}

@Inject
class SynchronousUserList {}

class UserController {
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/car.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export class CyclicEngine {
// @Inject(Engine)
annotate(Car, new Inject(Engine));

// @Inject
annotate(createEngine, new Inject());
// @Provide(Engine)
annotate(createEngine, new Provide(Engine));

Expand Down
Loading