Comparing version 3.1.0 to 3.2.0
# Changelog | ||
### 3.2.0 | ||
* add `asSingleton` registration method; | ||
### 3.1.0 | ||
@@ -4,0 +8,0 @@ |
import { Constructor, Container, RegistrationType, AbstractConstructor, ImplementationType, ImplementationTypeWithInjection } from './types'; | ||
declare class ContainerImpl implements Container { | ||
declare class ContainerImpl<RegisterTypeExtension = {}, RegisterInstanceExtension = {}> implements Container<RegisterTypeExtension, RegisterInstanceExtension> { | ||
protected singletons: Map<ImplementationTypeWithInjection<any>, Object>; | ||
@@ -7,12 +7,25 @@ protected instances: Map<RegistrationType<any>, any>; | ||
constructor(); | ||
/** register class */ | ||
registerType<TInstance>(implementationType: ImplementationType<TInstance>): { | ||
/** as super class */ | ||
as: <TBase extends Partial<TInstance>>(type: RegistrationType<TBase>) => { | ||
/** add parameters that will be passed to the class constructor */ | ||
with: (...injectionParams: any[]) => void; | ||
}; | ||
/** as singleton (optionally super class). Only if you didn't use @singleton decorator */ | ||
asSingleton: <TBase_1 extends Partial<TInstance>>(type?: RegistrationType<TBase_1> | undefined) => { | ||
/** add parameters that will be passed to the class constructor */ | ||
with: (...injectionParams: any[]) => void; | ||
}; | ||
/** add parameters that will be passed to the class constructor */ | ||
with: (...injectionParams: any[]) => void; | ||
}; | ||
} & RegisterTypeExtension; | ||
/** register any object as it constructor */ | ||
registerInstance<TInstance extends Object>(instance: TInstance): { | ||
/** or register the object as any class */ | ||
as: <TBase extends Partial<TInstance>>(type: RegistrationType<TBase>) => void; | ||
}; | ||
} & RegisterInstanceExtension; | ||
/** instantiate (or get instance for singleton) by class */ | ||
resolve<TInstance>(type: Constructor<TInstance> | AbstractConstructor<TInstance>, ...args: any[]): TInstance | undefined; | ||
/** clear all registered classes and instances */ | ||
clear(): void; | ||
@@ -19,0 +32,0 @@ private internalResolve; |
@@ -5,2 +5,3 @@ "use strict"; | ||
const decorators_1 = require("./decorators"); | ||
const singleton_1 = require("./decorators/singleton"); | ||
const errors_1 = require("./errors"); | ||
@@ -14,8 +15,13 @@ const utils_1 = require("./utils"); | ||
} | ||
/** register class */ | ||
registerType(implementationType) { | ||
const withInjection = (...injectionParams) => { | ||
decorators_1.setInjectedParams(implementationType, injectionParams); | ||
(0, decorators_1.setInjectedParams)(implementationType, injectionParams); | ||
}; | ||
this.dependencies.set(implementationType, implementationType); | ||
return { | ||
if (!(0, decorators_1.getDependencies)(implementationType).length) { | ||
(0, decorators_1.di)(implementationType); | ||
} | ||
return Object.assign({ | ||
/** as super class */ | ||
as: (type) => { | ||
@@ -25,8 +31,24 @@ this.dependencies.delete(implementationType); | ||
return { | ||
/** add parameters that will be passed to the class constructor */ | ||
with: withInjection, | ||
}; | ||
}, | ||
with: withInjection, | ||
}; | ||
}, | ||
/** as singleton (optionally super class). Only if you didn't use @singleton decorator */ | ||
asSingleton: (type) => { | ||
if (type) { | ||
this.dependencies.delete(implementationType); | ||
this.dependencies.set(type, implementationType); | ||
} | ||
if (!(0, decorators_1.isSingleton)(implementationType)) { | ||
(0, singleton_1.modifySingleton)(implementationType); | ||
} | ||
return { | ||
/** add parameters that will be passed to the class constructor */ | ||
with: withInjection, | ||
}; | ||
}, | ||
/** add parameters that will be passed to the class constructor */ | ||
with: withInjection }, {}); | ||
} | ||
/** register any object as it constructor */ | ||
registerInstance(instance) { | ||
@@ -37,3 +59,4 @@ const constructor = instance.constructor; | ||
} | ||
return { | ||
return Object.assign({ | ||
/** or register the object as any class */ | ||
as: (type) => { | ||
@@ -44,5 +67,5 @@ if (constructor) { | ||
this.instances.set(type, instance); | ||
}, | ||
}; | ||
} }, {}); | ||
} | ||
/** instantiate (or get instance for singleton) by class */ | ||
resolve(type, ...args) { | ||
@@ -62,2 +85,3 @@ const trace = new utils_1.Trace(type.name); | ||
} | ||
/** clear all registered classes and instances */ | ||
clear() { | ||
@@ -80,3 +104,3 @@ this.instances.clear(); | ||
} | ||
if (decorators_1.isSingleton(implementation)) { | ||
if ((0, decorators_1.isSingleton)(implementation)) { | ||
const singletons = this.getSingletons(); | ||
@@ -90,3 +114,3 @@ if (singletons.has(implementation)) { | ||
const injectionParams = [ | ||
...decorators_1.getInjectedParams(implementation), | ||
...(0, decorators_1.getInjectedParams)(implementation), | ||
...args, | ||
@@ -96,3 +120,3 @@ ]; | ||
let injectionParamsIndex = 0; | ||
const dependencies = decorators_1.getDependencies(implementation); | ||
const dependencies = (0, decorators_1.getDependencies)(implementation); | ||
if (dependencies.length) { | ||
@@ -131,3 +155,3 @@ let has = true; | ||
const target = new implementation(...injectableArguments); | ||
if (decorators_1.isSingleton(implementation)) { | ||
if ((0, decorators_1.isSingleton)(implementation)) { | ||
const singletons = this.getSingletons(); | ||
@@ -134,0 +158,0 @@ singletons.set(implementation, target); |
@@ -20,3 +20,3 @@ "use strict"; | ||
if (type instanceof Object && !primitiveConstructors.includes(type)) { | ||
inject_1.inject(type)(constructor, type.name, index); | ||
(0, inject_1.inject)(type)(constructor, type.name, index); | ||
} | ||
@@ -23,0 +23,0 @@ }); |
export * from './dependencies'; | ||
export * from './di'; | ||
export * from './inject'; | ||
export * from './singleton'; | ||
export { singleton, isSingleton } from './singleton'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isSingleton = exports.singleton = void 0; | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./dependencies"), exports); | ||
tslib_1.__exportStar(require("./di"), exports); | ||
tslib_1.__exportStar(require("./inject"), exports); | ||
tslib_1.__exportStar(require("./singleton"), exports); | ||
(0, tslib_1.__exportStar)(require("./dependencies"), exports); | ||
(0, tslib_1.__exportStar)(require("./di"), exports); | ||
(0, tslib_1.__exportStar)(require("./inject"), exports); | ||
var singleton_1 = require("./singleton"); | ||
Object.defineProperty(exports, "singleton", { enumerable: true, get: function () { return singleton_1.singleton; } }); | ||
Object.defineProperty(exports, "isSingleton", { enumerable: true, get: function () { return singleton_1.isSingleton; } }); | ||
//# sourceMappingURL=index.js.map |
import { Constructor } from '../types'; | ||
declare function singleton<TClass extends Constructor>(constructor: TClass): TClass; | ||
declare function modifySingleton<TClass extends Constructor>(constructor: TClass): void; | ||
declare function isSingleton<TClass extends Constructor>(constructor: TClass): boolean; | ||
export { singleton, isSingleton }; | ||
export { singleton, modifySingleton, isSingleton }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isSingleton = exports.singleton = void 0; | ||
exports.isSingleton = exports.modifySingleton = exports.singleton = void 0; | ||
const di_1 = require("./di"); | ||
@@ -8,8 +8,12 @@ const InheritancePreserver_1 = require("./InheritancePreserver"); | ||
function singleton(constructor) { | ||
modifySingleton(constructor); | ||
(0, di_1.di)(constructor); | ||
return constructor; | ||
} | ||
exports.singleton = singleton; | ||
function modifySingleton(constructor) { | ||
constructor[symbols_1.singletonSymbol] = true; | ||
InheritancePreserver_1.InheritancePreserver.constructorModified(constructor); | ||
di_1.di(constructor); | ||
return constructor; | ||
} | ||
exports.singleton = singleton; | ||
exports.modifySingleton = modifySingleton; | ||
function isSingleton(constructor) { | ||
@@ -16,0 +20,0 @@ const modifiedConstructor = InheritancePreserver_1.InheritancePreserver.getModifiedConstructor(constructor); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./CircularDependencyError"), exports); | ||
(0, tslib_1.__exportStar)(require("./CircularDependencyError"), exports); | ||
//# sourceMappingURL=index.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./ContainerImpl"), exports); | ||
tslib_1.__exportStar(require("./decorators"), exports); | ||
tslib_1.__exportStar(require("./errors"), exports); | ||
tslib_1.__exportStar(require("./types"), exports); | ||
tslib_1.__exportStar(require("./symbols"), exports); | ||
(0, tslib_1.__exportStar)(require("./ContainerImpl"), exports); | ||
(0, tslib_1.__exportStar)(require("./decorators"), exports); | ||
(0, tslib_1.__exportStar)(require("./errors"), exports); | ||
(0, tslib_1.__exportStar)(require("./types"), exports); | ||
(0, tslib_1.__exportStar)(require("./symbols"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -14,20 +14,29 @@ import { singletonSymbol, dependenciesSymbol, injectionSymbol, inheritancePreserveSymbol } from './symbols'; | ||
declare type RegistrationType<TInstance> = Constructor<TInstance> | AbstractConstructor<TInstance>; | ||
interface DependencyRegistrator { | ||
interface WithInjectionParams { | ||
/** add parameters that will be passed to the class constructor */ | ||
with: (...injectionParams: any[]) => void; | ||
} | ||
interface DependencyRegistrator<RegisterTypeExtension = {}, RegisterInstanceExtension = {}> { | ||
/** register class */ | ||
registerType: <TClass>(implementationType: ImplementationType<TClass>) => { | ||
as: <TBase extends Partial<TClass>>(type: RegistrationType<TBase>) => { | ||
with: (...injectionParams: any[]) => void; | ||
}; | ||
with: (...injectionParams: any[]) => void; | ||
}; | ||
/** as super class */ | ||
as: <TBase extends Partial<TClass>>(type: RegistrationType<TBase>) => WithInjectionParams; | ||
/** as singleton (optionally super class) */ | ||
asSingleton: <TBase extends Partial<TClass>>(type?: RegistrationType<TBase>) => WithInjectionParams; | ||
} & WithInjectionParams & RegisterTypeExtension; | ||
/** register any object as it constructor */ | ||
registerInstance: <TInstance extends Object>(instance: TInstance) => { | ||
/** or register the object as any class */ | ||
as: <TBase extends Partial<TInstance>>(type: RegistrationType<TBase>) => void; | ||
}; | ||
} & RegisterInstanceExtension; | ||
} | ||
declare type Resolver = <TInstance>(type: Constructor<TInstance> | AbstractConstructor<TInstance>, ...args: any[]) => TInstance | undefined; | ||
interface DependencyResolver { | ||
/** instantiate (or get instance for singleton) by class */ | ||
resolve: Resolver; | ||
/** clear all registered classes and instances */ | ||
clear(): void; | ||
} | ||
interface Container extends DependencyRegistrator, DependencyResolver { | ||
interface Container<RegisterTypeExtension = {}, RegisterInstanceExtension = {}> extends DependencyRegistrator<RegisterTypeExtension, RegisterInstanceExtension>, DependencyResolver { | ||
} | ||
export type { AbstractConstructor, Constructor, Container, Dependency, DependencyRegistrator, DependencyResolver, ImplementationType, ImplementationTypeWithInjection, RegistrationType, }; | ||
export type { AbstractConstructor, Constructor, Container, Dependency, DependencyRegistrator, DependencyResolver, ImplementationType, ImplementationTypeWithInjection, RegistrationType, WithInjectionParams, }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./Trace"), exports); | ||
(0, tslib_1.__exportStar)(require("./Trace"), exports); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "cheap-di", | ||
"version": "3.1.0", | ||
"version": "3.2.0", | ||
"description": "JavaScript dependency injection like Autofac in .Net", | ||
@@ -17,3 +17,3 @@ "scripts": { | ||
"tslib": "2.3.1", | ||
"typescript": "4.3.5" | ||
"typescript": "4.4.2" | ||
}, | ||
@@ -20,0 +20,0 @@ "files": [ |
@@ -90,3 +90,3 @@ # cheap-di | ||
```js | ||
import { dependencies } from 'cheap-di'; | ||
import { dependenciesSymbol } from 'cheap-di'; | ||
import { Logger } from './logger'; | ||
@@ -96,3 +96,3 @@ import { UserRepository } from './user-repository'; | ||
export class UserService { | ||
static [dependencies] = [UserRepository, Logger]; | ||
static [dependenciesSymbol] = [UserRepository, Logger]; | ||
@@ -120,3 +120,2 @@ constructor(userRepository, logger) { | ||
import { container } from 'cheap-di'; | ||
import { ConsoleLogger } from './console-logger'; | ||
@@ -136,3 +135,2 @@ import { FakeUserRepository } from './fake-user-repository'; | ||
import { container } from 'cheap-di'; | ||
import { UserService } from './user-service'; | ||
@@ -147,7 +145,7 @@ | ||
```js | ||
import { dependencies, container } from 'cheap-di'; | ||
import { dependenciesSymbol, container } from 'cheap-di'; | ||
// ... | ||
export class UserService { | ||
static [dependencies] = [UserRepository, undefined, Logger]; | ||
static [dependenciesSymbol] = [UserRepository, undefined, Logger]; | ||
@@ -189,2 +187,53 @@ constructor(userRepository, someMessage, logger) { | ||
You can use typescript reflection for auto resolve your class dependencies and inject them. | ||
For that you should add lines below to your `tsconfig.json`: | ||
``` | ||
"emitDecoratorMetadata": true, | ||
"experimentalDecorators": true, | ||
``` | ||
and add any class-decorator to your class. For example: | ||
`metadata.ts` | ||
```ts | ||
export const metadata = <T>(constructor: T): T => constructor; | ||
``` | ||
`service.ts` | ||
```ts | ||
import { metadata } from './metadata'; | ||
import { Logger } from './logger'; | ||
@metadata | ||
export class Service { | ||
constructor(private logger: Logger) {} | ||
doSome() { | ||
this.logger.debug('Hello world!'); | ||
} | ||
} | ||
``` | ||
But you should explicitly register each type like this to resolve his dependencies by container: | ||
```ts | ||
import { container } from 'cheap-di'; | ||
import { Service } from './service'; | ||
container.registerType(Service); | ||
const service = container.resolve(Service); | ||
service.doSome(); | ||
``` | ||
<h3>In this scenario you don't need decorators from next section!</h3> | ||
--- | ||
### Decorators | ||
If you want to use any of next decorators, you should add line below to your `tsconfig.json`: | ||
``` | ||
"experimentalDecorators": true, | ||
``` | ||
#### Dependencies | ||
@@ -205,4 +254,3 @@ | ||
private logger: Logger, | ||
) { | ||
} | ||
) {} | ||
@@ -209,0 +257,0 @@ list() { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
61638
669
355