🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

container-ioc

Package Overview
Dependencies
Maintainers
2
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

container-ioc - npm Package Compare versions

Comparing version

to
1.7.3

10

CHANGELOG.md

@@ -0,1 +1,11 @@

<a name="1.7.3"></a>
# [1.7.3]() (2017-10-07)
### API changes
#### Container
* **Added option parameter to constructor**. - options object has two attributes: (parent and defaultLifeTime).
### Fixed
* **Factories always resolve instances**.
<a name="1.7.0"></a>

@@ -2,0 +12,0 @@ # [1.7.0]() (2017-10-07)

15

dist/lib/container.d.ts
import { IInjectionInstance, ProviderToken, RegistrationProvider } from './interfaces';
import { IContainer } from './container.interface';
import { IContainer, IContainerOptions } from './container.interface';
export declare class Container implements IContainer {
private static DEFAULT_LIFE_TIME;
private registry;
private parent;
private registry;
constructor(parent?: IContainer | undefined);
private defaultLifeTime;
constructor(options?: IContainerOptions);
register(provider: RegistrationProvider | RegistrationProvider[]): void;
resolve(token: ProviderToken): IInjectionInstance;
createScope(): IContainer;
createChild(): IContainer;
setParent(parent: IContainer): void;
createChild(): IContainer;
private resolveInternal(token, traceMessage?);
private registerAll(providers);
private registerOne(provider);
private createInstance(cls, message);
private convertTokensToInjectionMd(tokens);
private instantiateWithFactory(factory, traceMessage);
private nornalizeProvider(provider);

@@ -22,3 +25,3 @@ private normalizeSingleProvider(provider);

private isInjectable(cls);
private getInjections(cls);
private retrieveInjectionsFromClass(cls);
}

6

dist/lib/container.interface.d.ts

@@ -1,2 +0,6 @@

import { IInjectionInstance, ProviderToken, RegistrationProvider } from './interfaces';
import { IInjectionInstance, ProviderToken, RegistrationProvider, LifeTime } from './interfaces';
export interface IContainerOptions {
parent?: IContainer;
defaultLifeTime?: LifeTime;
}
export interface IContainer {

@@ -3,0 +7,0 @@ register(provider: RegistrationProvider | RegistrationProvider[]): void;

@@ -10,5 +10,9 @@ "use strict";

class Container {
constructor(parent) {
this.parent = parent;
constructor(options) {
this.registry = new Map();
this.defaultLifeTime = Container.DEFAULT_LIFE_TIME;
if (options) {
this.parent = options.parent;
this.defaultLifeTime = options.defaultLifeTime || this.defaultLifeTime;
}
}

@@ -29,10 +33,10 @@ register(provider) {

createScope() {
return new Container(this);
return new Container({ parent: this });
}
createChild() {
return this.createScope();
}
setParent(parent) {
this.parent = parent;
}
createChild() {
return new Container(this);
}
resolveInternal(token, traceMessage) {

@@ -50,15 +54,3 @@ traceMessage = this.buildTraceMessage(token, traceMessage);

}
if (registryData.factory) {
let injections = [];
if (registryData.injections) {
injections = registryData.injections.map(i => this.resolveInternal(i, traceMessage));
}
return registryData.factory(...injections);
}
const constructor = registryData.cls;
const isInjectable = this.isInjectable(constructor);
if (!isInjectable) {
throw new exceptions_1.ClassNotInjectableError(constructor.name);
}
const instance = this.createInstance(constructor, traceMessage);
const instance = this.instantiateWithFactory(registryData.factory, traceMessage);
if (registryData.lifeTime === interfaces_1.LifeTime.Persistent) {

@@ -78,20 +70,44 @@ registryData.instance = instance;

}
else if (provider.useClass) {
registryData.cls = provider.useClass;
else {
const factoryValue = provider.useFactory || provider.useClass;
const isClass = this.isInjectable(factoryValue);
registryData.factory = {
value: factoryValue,
isClass
};
if (isClass) {
registryData.factory.inject = this.retrieveInjectionsFromClass(registryData.factory.value);
}
else {
registryData.factory.inject = this.convertTokensToInjectionMd(provider.inject);
}
registryData.lifeTime = provider.lifeTime || this.defaultLifeTime;
}
else if (provider.useFactory) {
registryData.factory = provider.useFactory;
registryData.injections = provider.inject;
}
registryData.lifeTime = provider.lifeTime || interfaces_1.LifeTime.Persistent;
this.registry.set(provider.token, registryData);
}
createInstance(cls, message) {
const injectionsMd = this.getInjections(cls);
const resolvedInjections = injectionsMd.map(injectionMd => this.resolveInternal(injectionMd.token, message));
convertTokensToInjectionMd(tokens) {
let injections = [];
if (tokens) {
injections = tokens.map((token, index) => {
return {
token,
parameterIndex: index
};
});
}
return injections;
}
instantiateWithFactory(factory, traceMessage) {
const injections = factory.inject;
const resolvedInjections = injections.map(injection => this.resolveInternal(injection.token, traceMessage));
const args = [];
injectionsMd.forEach((injection, index) => {
injections.forEach((injection, index) => {
args[injection.parameterIndex] = resolvedInjections[index];
});
return new cls(...args);
if (factory.isClass) {
return new factory.value(...args);
}
else {
return factory.value(...args);
}
}

@@ -145,6 +161,8 @@ nornalizeProvider(provider) {

}
getInjections(cls) {
return MetadataAnnotator.getMetadata(keys_1.INJECTIONS_MD_KEY, cls) || [];
retrieveInjectionsFromClass(cls) {
const injections = MetadataAnnotator.getMetadata(keys_1.INJECTIONS_MD_KEY, cls) || [];
return this.convertTokensToInjectionMd(injections);
}
}
Container.DEFAULT_LIFE_TIME = interfaces_1.LifeTime.Persistent;
exports.Container = Container;

@@ -11,8 +11,3 @@ "use strict";

const injectionMd = MetadataAnnotator.getMetadata(keys_1.INJECTIONS_MD_KEY, target) || [];
injections.forEach((injectionToken, injectionIndex) => {
injectionMd.push({
token: injectionToken,
parameterIndex: injectionIndex
});
});
injections.forEach(token => injectionMd.push(token));
MetadataAnnotator.defineMetadata(keys_1.INJECTIONS_MD_KEY, injectionMd, target);

@@ -26,6 +21,3 @@ }

const injections = MetadataAnnotator.getMetadata(keys_1.INJECTIONS_MD_KEY, target) || [];
injections.push({
token,
parameterIndex
});
injections.push(token);
MetadataAnnotator.defineMetadata(keys_1.INJECTIONS_MD_KEY, injections, target);

@@ -32,0 +24,0 @@ };

@@ -1,7 +0,11 @@

import { IConstructor, IInjectionInstance, LifeTime, ProviderToken } from './interfaces';
import { IConstructor, IInjectionInstance, IInjectionMd, LifeTime } from './interfaces';
export declare type FactoryFunction = (...args: any[]) => any;
export interface IFactory {
value: IConstructor | FactoryFunction;
isClass: boolean;
inject?: IInjectionMd[];
}
export interface IRegistryData {
instance: IInjectionInstance;
cls: IConstructor;
factory: (...args: any[]) => any;
injections: ProviderToken[];
factory: IFactory;
lifeTime: LifeTime;

@@ -11,6 +15,4 @@ }

instance: IInjectionInstance;
cls: IConstructor;
factory: (...args: any[]) => any;
injections: ProviderToken[];
factory: IFactory;
lifeTime: LifeTime;
}
{
"name": "container-ioc",
"version": "1.7.1",
"version": "1.7.3",
"description": "Dependency Injection and Inversion of Control (IoC) container",

@@ -5,0 +5,0 @@ "author": "Alexander Kozlov",

@@ -107,3 +107,4 @@ ![alt text](http://abcselfstorageperth.com.au/wp-content/uploads/2014/08/icon-container-storage1.png)

### Life Time control.
> By default, containers resolve singletons when registering with **useClass**. Change it by setting **lifeTime** attribute to **LifeTime.PerRequest**.
> By default, containers resolve singletons when using **useClass** and **useFactory**.
Default life time for all items in a container can be set by passing an option object to it's contructor with **defailtLifeTime** attribute. Possible values: **LifeTime.PerRequest** (resolves instances) and **LifeTime.Persistent** (resolves singletons);

@@ -113,22 +114,44 @@ ```typescript

const container = new Container({
defaultLifeTime: LifeTime.PerRequest
});
```
> You can also specify life time individually for each item in a container by specifying **lifeTime** attribute.
```typescript
container.register([
{ token: TService, useClass: Service, lifeTime: LifeTime.PerRequest }
{
token: TService,
useClass: Service,
lifeTime: LifeTime.PerRequest
}
]);
```
```typescript
container.register([
{
token: TService,
useFactory: () => {
return {
serve(): void {}
}
},
lifeTime: LifeTime.Persistent
}
]);
```
### Hierarchical containers.
> If container can't find value, it will look it up in ascendant containers.
> If a container can't find a value within itself, it will look it up in ascendant containers. There a 3 ways to set a parent for a container.
###### 1. Container.createChild() method.
```typescript
const parentContainer = new Container();
const childContainer = parentContainer.createChild();
```
let parentContainer = new Container();
let childContainer = parentContainer.createChild();
parentContainer.register({ token: TApplication, useClass: Application });
childContainer.resolve(TApplication);
```
> You can also assign parent container to any other container
###### 2. Container.setParent() method.
```typescript
let parent = new Container();
let child = new Container();
const parent = new Container();
const child = new Container();

@@ -138,2 +161,10 @@ child.setParent(parent);

###### 3. Via Container's constructor with options.
```typescript
const parent = new Container();
const child = new Container({
parent: parent
});
```
### Using Factories

@@ -140,0 +171,0 @@ ```typescript