Skip to content
This repository was archived by the owner on Sep 4, 2020. It is now read-only.

Commit 2bb3c78

Browse files
feat(core): support AOT
BREAKING CHANGE: must specify provider dependencies To migrate your code follow the example below: Before: providers: [ ...ProvideOnce(MyService) ], After: providers: [ ...ProvideOnce(MyService, [DependantService]) ], See the README for more details.
1 parent f8494f0 commit 2bb3c78

File tree

3 files changed

+74
-26
lines changed

3 files changed

+74
-26
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,41 @@ npm install angular-provide-once --save
2929
import { NgModule } from '@angular/core';
3030
import { ProvideOnce } from 'angular-provide-once';
3131

32+
import { DependantService } from './dependant-service';
3233
import { MyService } from './my-service';
34+
import { OtherService } from './other-service';
3335

3436
@NgModule({
3537
imports: [],
3638
providers: [
37-
...ProvideOnce(MyService)
39+
OtherService,
40+
DependantService,
41+
...ProvideOnce(MyService, [DependantService])
3842
],
3943
declarations: []
4044
})
4145
export class MyModule { }
4246
```
4347

48+
## Api
49+
50+
## `...ProvideOnce(targetService[, dependencyArray])`
51+
52+
## Paramaters
53+
54+
### targetService
55+
56+
The service that should be provided once.
57+
58+
### dependencyArray
59+
60+
An optional array of services that the targetService depends on. Only include immediate dependencies (not dependencies of dependencies).
61+
62+
## Return value
63+
64+
`ProvideOnce` returns an array of Providers. Use the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator) (e.g. `...ProvideOnce`) to include it along with other services.
65+
66+
4467
## License
4568

4669
angular-provide-once is licensed under the MIT Open Source license. For more information, see the [LICENSE](LICENSE) file in this repository.

src/provide-once.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,27 @@ import {
88
ValueProvider } from '@angular/core';
99
import { reflector } from './private_import_core';
1010

11-
export function ProvideOnce<T>(ProvidableType: Type<T>): Array<FactoryProvider | ValueProvider> {
12-
return CreateProviders(new OpaqueToken('providable_type'), ProvidableType);
11+
export function ProvideOnce<T>(ProvidableType: Type<T>, params = []): Array<FactoryProvider | ValueProvider> {
12+
return CreateProviders(new OpaqueToken('providable_type'), ProvidableType, params);
1313
}
1414

1515
export function CreateProviders<T>(
1616
TOKEN: OpaqueToken,
17-
ProvidableType: Type<T>): Array<FactoryProvider | ValueProvider> {
17+
ProvidableType: Type<T>,
18+
params): Array<FactoryProvider | ValueProvider> {
1819
return [
1920
{
2021
provide: TOKEN,
2122
useValue: ProvidableType
2223
},
2324
{
2425
provide: ProvidableType,
25-
deps: [[new Optional(), new SkipSelf(), ProvidableType], TOKEN],
26+
deps: [[new Optional(), new SkipSelf(), ProvidableType], TOKEN, ...params],
2627
useFactory: PROVIDER_FACTORY
2728
}
2829
];
2930
}
3031

31-
export function PROVIDER_FACTORY<T>(parentInstance: Type<T>, Token: Type<T>): Type<T> {
32-
return parentInstance || ReflectiveInjector
33-
.resolveAndCreate([Token, ...reflector.parameters(Token)])
34-
.get(Token);
32+
export function PROVIDER_FACTORY<T>(parentInstance: Type<T>, Token: Type<T>, ...args): Type<T> {
33+
return parentInstance || reflector.factory(Token).apply(this, [...args]);
3534
}

tests/provide-once.spec.ts

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,38 @@
11
/* tslint:disable:no-unused-variable */
22
import { Injectable, ReflectiveInjector } from '@angular/core';
33
import { async, inject, TestBed } from '@angular/core/testing';
4+
import { Observable, ReplaySubject, Subject } from 'rxjs/Rx';
45

56
import { ProvideOnce } from '../src/provide-once';
67

8+
@Injectable()
9+
export class ClassA { }
10+
11+
@Injectable()
12+
export class ClassB {
13+
constructor(public classA: ClassA) { }
14+
}
15+
16+
@Injectable()
17+
export class ClassC {
18+
constructor(public classB: ClassB) { }
19+
}
20+
721
describe('Function: ProvideOnce', () => {
22+
beforeEach(() => {
23+
TestBed.configureTestingModule({
24+
providers: [
25+
ClassA,
26+
...ProvideOnce(ClassB, [ClassA]),
27+
...ProvideOnce(ClassC, [ClassB])
28+
]
29+
});
30+
});
31+
32+
beforeEach(async(() => {
33+
TestBed.compileComponents();
34+
}));
35+
836
it('should create a provider', () => {
937
const service = new ClassA();
1038
const providers: any = ProvideOnce(ClassA);
@@ -21,23 +49,21 @@ describe('Function: ProvideOnce', () => {
2149
expect(newService instanceof ClassA).toBe(true);
2250
});
2351

24-
it('should resolve dependencies in the provided factory function', () => {
52+
it('should resolve dependencies in the provided factory function', inject([ClassB], (service: ClassB) => {
2553
const serviceA: ClassA = new ClassA();
2654
const serviceB: ClassB = new ClassB(serviceA);
27-
const providers: any = ProvideOnce(ClassB);
28-
const factory = providers[1].useFactory;
29-
const newService: ClassB = factory(null, ClassB);
30-
expect(newService instanceof ClassA).toBe(false);
31-
expect(newService instanceof ClassB).toBe(true);
32-
expect(serviceB.classA instanceof ClassA).toBe(true);
33-
expect(newService.classA instanceof ClassA).toBe(true);
34-
});
35-
});
55+
expect(service instanceof ClassA).toBe(false);
56+
expect(service instanceof ClassB).toBe(true);
57+
expect(service.classA instanceof ClassA).toBe(true);
58+
}));
3659

37-
@Injectable()
38-
export class ClassA { }
39-
40-
@Injectable()
41-
export class ClassB {
42-
constructor(public classA: ClassA) { }
43-
}
60+
it('should resolve dependencies in the provided factory function', inject([ClassC], (service: ClassC) => {
61+
const serviceA: ClassA = new ClassA();
62+
const serviceB: ClassB = new ClassB(serviceA);
63+
const serviceC: ClassC = new ClassC(serviceB);
64+
expect(service instanceof ClassB).toBe(false);
65+
expect(service instanceof ClassC).toBe(true);
66+
expect(serviceC.classB instanceof ClassB).toBe(true);
67+
expect(service.classB.classA instanceof ClassA).toBe(true);
68+
}));
69+
});

0 commit comments

Comments
 (0)