Skip to content

Commit

Permalink
[chore] Split code into separate files for better tree-shaking (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
Xapphire13 authored Apr 16, 2019
1 parent 49097b4 commit b8f1ce0
Show file tree
Hide file tree
Showing 25 changed files with 177 additions and 137 deletions.
2 changes: 1 addition & 1 deletion src/decorators/auto-injectable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {constructor} from "../types";
import constructor from "../types/constructor";
import {getParamInfo} from "../reflection-helpers";
import {instance as globalContainer} from "../dependency-container";

Expand Down
2 changes: 1 addition & 1 deletion src/decorators/inject.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {INJECTION_TOKEN_METADATA_KEY} from "../reflection-helpers";
import {InjectionToken} from "../providers";
import InjectionToken from "../providers/injection-token";

/**
* Parameter decorator factory that allows for interface information to be stored in the constructor's metadata
Expand Down
2 changes: 1 addition & 1 deletion src/decorators/injectable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {constructor} from "../types";
import constructor from "../types/constructor";
import {getParamInfo} from "../reflection-helpers";
import {typeInfo} from "../dependency-container";

Expand Down
5 changes: 3 additions & 2 deletions src/decorators/registry.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {InjectionToken, Provider} from "../providers";
import {RegistrationOptions} from "../types";
import Provider from "../providers/provider";
import InjectionToken from "../providers/injection-token";
import RegistrationOptions from "../types/registration-options";
import {instance as globalContainer} from "../dependency-container";

/**
Expand Down
2 changes: 1 addition & 1 deletion src/decorators/singleton.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {constructor} from "../types";
import constructor from "../types/constructor";
import injectable from "./injectable";
import {instance as globalContainer} from "../dependency-container";

Expand Down
49 changes: 26 additions & 23 deletions src/dependency-container.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import * as Types from "./types";
import DependencyContainer from "./types/dependency-container";
import {
ClassProvider,
FactoryProvider,
InjectionToken,
Provider,
TokenProvider,
ValueProvider,
isClassProvider,
isFactoryProvider,
isNormalToken,
isTokenProvider,
isValueProvider
} from "./providers";
import {RegistrationOptions, constructor} from "./types";
import Provider from "./providers/provider";
import FactoryProvider from "./providers/factory-provider";
import InjectionToken from "./providers/injection-token";
import TokenProvider from "./providers/token-provider";
import ValueProvider from "./providers/value-provider";
import ClassProvider from "./providers/class-provider";
import RegistrationOptions from "./types/registration-options";
import constructor from "./types/constructor";

type Registration<T = any> = {
provider: Provider<T>;
Expand All @@ -23,10 +24,10 @@ type Registration<T = any> = {
export const typeInfo = new Map<constructor<any>, any[]>();

/** Dependency Container */
export class DependencyContainer implements Types.DependencyContainer {
class InternalDependencyContainer implements DependencyContainer {
private _registry = new Map<InjectionToken<any>, Registration>();

public constructor(private parent?: DependencyContainer) {}
public constructor(private parent?: InternalDependencyContainer) {}

/**
* Register a dependency provider.
Expand All @@ -36,26 +37,26 @@ export class DependencyContainer implements Types.DependencyContainer {
public register<T>(
token: InjectionToken<T>,
provider: ValueProvider<T>
): DependencyContainer;
): InternalDependencyContainer;
public register<T>(
token: InjectionToken<T>,
provider: FactoryProvider<T>
): DependencyContainer;
): InternalDependencyContainer;
public register<T>(
token: InjectionToken<T>,
provider: TokenProvider<T>,
options?: RegistrationOptions
): DependencyContainer;
): InternalDependencyContainer;
public register<T>(
token: InjectionToken<T>,
provider: ClassProvider<T>,
options?: RegistrationOptions
): DependencyContainer;
): InternalDependencyContainer;
public register<T>(
token: InjectionToken<T>,
provider: Provider<T>,
options: RegistrationOptions = {singleton: false}
): DependencyContainer {
): InternalDependencyContainer {
if (options.singleton) {
if (isValueProvider(provider) || isFactoryProvider(provider)) {
throw "Cannot use {singleton: true} with ValueProviders or FactoryProviders";
Expand All @@ -70,7 +71,7 @@ export class DependencyContainer implements Types.DependencyContainer {
public registerType<T>(
from: InjectionToken<T>,
to: InjectionToken<T>
): DependencyContainer {
): InternalDependencyContainer {
if (isNormalToken(to)) {
return this.register(from, {
useToken: to
Expand All @@ -85,7 +86,7 @@ export class DependencyContainer implements Types.DependencyContainer {
public registerInstance<T>(
token: InjectionToken<T>,
instance: T
): DependencyContainer {
): InternalDependencyContainer {
return this.register(token, {
useValue: instance
});
Expand All @@ -94,15 +95,15 @@ export class DependencyContainer implements Types.DependencyContainer {
public registerSingleton<T>(
from: InjectionToken<T>,
to: InjectionToken<T>
): DependencyContainer;
): InternalDependencyContainer;
public registerSingleton<T>(
token: constructor<T>,
to?: constructor<any>
): DependencyContainer;
): InternalDependencyContainer;
public registerSingleton<T>(
from: InjectionToken<T>,
to?: InjectionToken<T>
): DependencyContainer {
): InternalDependencyContainer {
if (isNormalToken(from)) {
if (isNormalToken(to)) {
return this.register(
Expand Down Expand Up @@ -198,8 +199,8 @@ export class DependencyContainer implements Types.DependencyContainer {
this._registry.clear();
}

public createChildContainer(): Types.DependencyContainer {
return new DependencyContainer(this);
public createChildContainer(): DependencyContainer {
return new InternalDependencyContainer(this);
}

private getRegistration<T>(token: InjectionToken<T>): Registration | null {
Expand Down Expand Up @@ -231,4 +232,6 @@ export class DependencyContainer implements Types.DependencyContainer {
}
}

export const instance: Types.DependencyContainer = new DependencyContainer();
export const instance: DependencyContainer = new InternalDependencyContainer();

export default instance;
5 changes: 5 additions & 0 deletions src/factories/factory-function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import DependencyContainer from "../types/dependency-container";

type FactoryFunction<T> = (dependencyContainer: DependencyContainer) => T;

export default FactoryFunction;
5 changes: 5 additions & 0 deletions src/factories/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export {default as FactoryFunction} from "./factory-function";
export {default as instanceCachingFactory} from "./instance-caching-factory";
export {
default as predicateAwareClassFactory
} from "./predicate-aware-class-factory";
14 changes: 14 additions & 0 deletions src/factories/instance-caching-factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import DependencyContainer from "../types/dependency-container";
import FactoryFunction from "./factory-function";

export default function instanceCachingFactory<T>(
factoryFunc: FactoryFunction<T>
): FactoryFunction<T> {
let instance: T;
return (dependencyContainer: DependencyContainer) => {
if (instance == undefined) {
instance = factoryFunc(dependencyContainer);
}
return instance;
};
}
26 changes: 4 additions & 22 deletions src/factories.ts → ...actories/predicate-aware-class-factory.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,15 @@
import {DependencyContainer, constructor} from "./types";
import DependencyContainer from "../types/dependency-container";
import constructor from "../types/constructor";
import FactoryFunction from "./factory-function";

export type FactoryFunction<T> = (
dependencyContainer: DependencyContainer
) => T;

export function instanceCachingFactory<T>(
factoryFunc: FactoryFunction<T>
): FactoryFunction<T> {
let instance: T;

return (dependencyContainer: DependencyContainer) => {
if (instance == undefined) {
instance = factoryFunc(dependencyContainer);
}

return instance;
};
}

export function predicateAwareClassFactory<T>(
export default function predicateAwareClassFactory<T>(
predicate: (dependencyContainer: DependencyContainer) => boolean,
trueConstructor: constructor<T>,
falseConstructor: constructor<T>,
useCaching = true
): FactoryFunction<T> {
let instance: T;
let previousPredicate: boolean;

return (dependencyContainer: DependencyContainer) => {
const currentPredicate = predicate(dependencyContainer);
if (!useCaching || previousPredicate !== currentPredicate) {
Expand All @@ -36,7 +19,6 @@ export function predicateAwareClassFactory<T>(
instance = dependencyContainer.resolve(falseConstructor);
}
}

return instance;
};
}
5 changes: 1 addition & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import {DependencyContainer} from "./types";
import {instance} from "./dependency-container";

if (typeof Reflect === "undefined" || !Reflect.getMetadata) {
throw `tsyringe requires a reflect polyfill. Please add 'import "reflect-metadata"' to the top of your entry point.`;
}
Expand All @@ -9,4 +6,4 @@ export {DependencyContainer} from "./types";
export * from "./decorators";
export * from "./factories";
export * from "./providers";
export const container: DependencyContainer = instance;
export {instance as container} from "./dependency-container";
61 changes: 0 additions & 61 deletions src/providers.ts

This file was deleted.

12 changes: 12 additions & 0 deletions src/providers/class-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import constructor from "../types/constructor";
import Provider from "./provider";

export default interface ClassProvider<T> {
useClass: constructor<T>;
}

export function isClassProvider<T>(
provider: Provider<T>
): provider is ClassProvider<any> {
return !!(<ClassProvider<T>>provider).useClass;
}
17 changes: 17 additions & 0 deletions src/providers/factory-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import DependencyContainer from "../types/dependency-container";
import Provider from "./provider";

/**
* Provide a dependency using a factory.
* Unlike the other providers, this does not support instance caching. If
* you need instance caching, your factory method must implement it.
*/
export default interface FactoryProvider<T> {
useFactory: (dependencyContainer: DependencyContainer) => T;
}

export function isFactoryProvider<T>(
provider: Provider<T>
): provider is FactoryProvider<any> {
return !!(<FactoryProvider<T>>provider).useFactory;
}
9 changes: 9 additions & 0 deletions src/providers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export {default as ClassProvider, isClassProvider} from "./class-provider";
export {
default as FactoryProvider,
isFactoryProvider
} from "./factory-provider";
export {default as InjectionToken, isNormalToken} from "./injection-token";
export {default as Provider} from "./provider";
export {default as TokenProvider, isTokenProvider} from "./token-provider";
export {default as ValueProvider, isValueProvider} from "./value-provider";
11 changes: 11 additions & 0 deletions src/providers/injection-token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import constructor from "../types/constructor";

type InjectionToken<T = any> = constructor<T> | string | symbol;

export function isNormalToken(
token?: InjectionToken<any>
): token is string | symbol {
return typeof token === "string" || typeof token === "symbol";
}

export default InjectionToken;
12 changes: 12 additions & 0 deletions src/providers/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import ClassProvider from "./class-provider";
import ValueProvider from "./value-provider";
import TokenProvider from "./token-provider";
import FactoryProvider from "./factory-provider";

type Provider<T> =
| ClassProvider<T>
| ValueProvider<T>
| TokenProvider<T>
| FactoryProvider<T>;

export default Provider;
12 changes: 12 additions & 0 deletions src/providers/token-provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import InjectionToken from "./injection-token";
import Provider from "./provider";

export default interface TokenProvider<T> {
useToken: InjectionToken<T>;
}

export function isTokenProvider<T>(
provider: Provider<T>
): provider is TokenProvider<any> {
return !!(<TokenProvider<T>>provider).useToken;
}
Loading

0 comments on commit b8f1ce0

Please sign in to comment.