Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

Commit

Permalink
feat: add static factory setup
Browse files Browse the repository at this point in the history
  • Loading branch information
KnisterPeter committed Aug 6, 2018
1 parent 86d3074 commit d71f3f1
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 10 deletions.
38 changes: 28 additions & 10 deletions lib/tsdi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ export type ParameterMetadata = {
export type ComponentMetadata = {
fn: Constructable<any>;
options: IComponentOptions;
provider?: {
class: Constructable<any>;
method: string;
dependencies: Constructable<any>[];
};
constructorDependencies?: Constructable<any>[];
propertyDependencies?: { property: string; type: Constructable<any> }[];
};
Expand Down Expand Up @@ -430,9 +435,21 @@ export class TSDI {
);
}
log('create %o with %o', (metadata.fn as any).name, metadata.options);
const constructor: Constructable<T> = metadata.fn as any;
const parameters = this.getConstructorParameters(metadata);
const instance = new constructor(...parameters);

const instanciate = () => {
if (metadata.provider) {
return this.get(metadata.provider.class)[metadata.provider.method](
...metadata.provider.dependencies.map(dependency =>
this.get(dependency)
)
);
}
const constructor: Constructable<T> = metadata.fn as any;
const parameters = this.getConstructorParameters(metadata);
return new constructor(...parameters);
};

const instance = instanciate();
// note: This stores an incomplete instance (injects/properties/...)
// but it allows recursive use of injects
this.instances[idx] = instance;
Expand All @@ -446,15 +463,10 @@ export class TSDI {
if (awaiter) {
this.addInitializerPromise(
instance,
awaiter.then(
() => (instance as any)[init].call(instance) || Promise.resolve()
)
awaiter.then(() => instance[init].call(instance) || Promise.resolve())
);
} else {
this.addInitializerPromise(
instance,
(instance as any)[init].call(instance)
);
this.addInitializerPromise(instance, instance[init].call(instance));
}
} else if (awaiter) {
this.addInitializerPromise(instance, awaiter);
Expand Down Expand Up @@ -853,6 +865,11 @@ export class TSDI {
public configure(
component: Constructable<any>,
config: {
provider?: {
class: Constructable<any>;
method: string;
dependencies: Constructable<any>[];
};
constructorDependencies?: Constructable<any>[];
propertyDependencies?: {
property: string;
Expand All @@ -863,6 +880,7 @@ export class TSDI {
this.registerComponent({
fn: component,
options: {},
provider: config.provider,
constructorDependencies: config.constructorDependencies,
propertyDependencies: config.propertyDependencies
});
Expand Down
27 changes: 27 additions & 0 deletions tests/configure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,31 @@ describe('TSDI without reflection should be configurable', () => {
expect(tsdi.get(Class).dependency).toBeInstanceOf(Dependency);
expect(tsdi.get(Class).dependency2).toBeInstanceOf(Dependency);
});

it('to declare injections by providers', () => {
class Component {
// tslint:disable-next-line:no-parameter-properties
constructor(public dependency: Dependency) {}
}
class Dependency {}

class Provider {
public provide(dependency: Dependency): Component {
return new Component(dependency);
}
}

tsdi.configure(Dependency);
tsdi.configure(Provider);
tsdi.configure(Component, {
provider: {
class: Provider,
method: 'provide',
dependencies: [Dependency]
}
});

expect(tsdi.get(Component)).toBeInstanceOf(Component);
expect(tsdi.get(Component).dependency).toBeInstanceOf(Dependency);
});
});

0 comments on commit d71f3f1

Please sign in to comment.