Compare commits
6 Commits
Author | SHA1 | Date | |
---|---|---|---|
9bd899581f | |||
b43e4ee12f | |||
ef4a2295bf | |||
f4f8c7b78e | |||
beaad4f65e | |||
![]() |
95ef003e99 |
79
CHANGELOG.md
79
CHANGELOG.md
@@ -9,71 +9,90 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
## [0.4.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- feat: Export ImplementsStatic helper function
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
### Security
|
||||||
|
|
||||||
|
## [0.3.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- refactor: consolidate registration decorators
|
||||||
|
Introduced Register decorator to handle class and instance registration in the DI container.
|
||||||
|
Deprecated RegisterInstance in favor of Register, which now internally handles instance registration.
|
||||||
|
Added support for marking dependencies as deprecated with a warning logged upon first resolution.
|
||||||
|
Updated documentation with examples and notes on deprecation.
|
||||||
|
- tests: add mode parameter to RegisterInstanceDecorator
|
||||||
|
Introduced a mode parameter to the test_RegisterInstanceDecorator function allowing 'instance' or 'standalone' modes.
|
||||||
|
Updated test cases to utilize the new mode parameter when registering an instance.
|
||||||
|
Disabled specific ESLint rule in Decorators.test.ts for deprecation warnings.
|
||||||
|
Added an additional test call to test_RegisterInstanceDecorator with 'instance' mode.
|
||||||
|
- refactor: add region tags for overloads in Register.ts
|
||||||
|
|
||||||
## [0.2.0]
|
## [0.2.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Add pre release building to release workflow on dev/* branches an version changes.
|
- Add pre release building to release workflow on dev/\* branches an version changes.
|
||||||
- feat: Introduced a new CLI command `tsinjex-generate` to automate the generation of import statements for registered dependencies.
|
- feat: Introduced a new CLI command `tsinjex-generate` to automate the generation of import statements for registered dependencies.
|
||||||
The command scans `.ts` files for `@Register` and `@RegisterInstance` decorators and generates an `auto-imports.ts` file.
|
The command scans `.ts` files for `@Register` and `@RegisterInstance` decorators and generates an `auto-imports.ts` file.
|
||||||
This ensures that all registered dependencies are automatically included without requiring manual imports.
|
This ensures that all registered dependencies are automatically included without requiring manual imports.
|
||||||
The CLI can be executed via `npx tsinjex-generate` or added as a script in `package.json` for easier integration.
|
The CLI can be executed via `npx tsinjex-generate` or added as a script in `package.json` for easier integration.
|
||||||
|
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
## [0.0.14]
|
## [0.0.14]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added **ChangeLog** file and format it according to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
- Added **ChangeLog** file and format it according to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||||
- Added reference to **Semantic Versioning** in the changelog file. (History will be updated on time).
|
- Added reference to **Semantic Versioning** in the changelog file. (History will be updated on time).
|
||||||
- Version format is now `v0.0.0` instead of `0.0.0`. Changes to this are also reflected in the workflos.
|
- Version format is now `v0.0.0` instead of `0.0.0`. Changes to this are also reflected in the workflos.
|
||||||
- Add `Identifiers` and `Jest` Sections to the `README.md` file.
|
- Add `Identifiers` and `Jest` Sections to the `README.md` file.
|
||||||
- feat: Add new Error `InitializationError` to reflect errors during initialization of a dependency.
|
- feat: Add new Error `InitializationError` to reflect errors during initialization of a dependency.
|
||||||
- feat: Add initialization error handling and refactor Inject.
|
- feat: Add initialization error handling and refactor Inject.
|
||||||
- feat: After injecting a dependency, the lazzy loading getter will be replaced with the dependency itself.
|
- feat: After injecting a dependency, the lazzy loading getter will be replaced with the dependency itself.
|
||||||
- feat: remove the use of a private property to store the injected dependencies. Now the dependencies are stored in the property itself.
|
- feat: remove the use of a private property to store the injected dependencies. Now the dependencies are stored in the property itself.
|
||||||
- test: Add tests for the new features.
|
- test: Add tests for the new features.
|
||||||
|
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
- Deprecated the old version format `0.0.0`.
|
- Deprecated the old version format `0.0.0`.
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[unreleased]: https://github.com/PxaMMaxP/TSinjex/compare/0.0.14...HEAD
|
[unreleased]: https://github.com/20Max01/TSinjex/compare/0.0.14...HEAD
|
||||||
[0.0.14]: https://github.com/PxaMMaxP/TSinjex/compare/0.0.13...v0.0.14
|
[0.0.14]: https://github.com/20Max01/TSinjex/compare/0.0.13...v0.0.14
|
||||||
[0.2.00]: https://github.com/PxaMMaxP/TSinjex/compare/0.0.14...v0.2.0
|
[0.2.0]: https://github.com/20Max01/TSinjex/compare/v0.0.14...v0.2.0
|
||||||
|
[0.3.0]: https://github.com/20Max01/TSinjex/compare/v0.2.0...v0.3.0
|
||||||
|
[0.4.0]: https://github.com/20Max01/TSinjex/compare/v0.3.0...v0.4.0
|
||||||
|
7
package-lock.json
generated
7
package-lock.json
generated
@@ -1,17 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "ts-injex",
|
"name": "ts-injex",
|
||||||
"version": "0.0.9",
|
"version": "0.4.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ts-injex",
|
"name": "ts-injex",
|
||||||
"version": "0.0.9",
|
"version": "0.4.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
"jest-environment-jsdom": "^29.7.0"
|
"jest-environment-jsdom": "^29.7.0"
|
||||||
},
|
},
|
||||||
|
"bin": {
|
||||||
|
"tsinjex-generate": "bin/generate-imports.cjs"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@stylistic/eslint-plugin": "^2.6.2",
|
"@stylistic/eslint-plugin": "^2.6.2",
|
||||||
"@types/jest": "^29.5.12",
|
"@types/jest": "^29.5.12",
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ts-injex",
|
"name": "ts-injex",
|
||||||
"version": "0.2.0",
|
"version": "0.4.0",
|
||||||
"description": "Simple boilerplate code free dependency injection system for TypeScript.",
|
"description": "Simple boilerplate code free dependency injection system for TypeScript.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
@@ -63,4 +63,4 @@
|
|||||||
"LICENSE",
|
"LICENSE",
|
||||||
"package.json"
|
"package.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
@@ -282,6 +282,7 @@ export function test_RegisterInstanceDecorator(
|
|||||||
Container: ITSinjex_,
|
Container: ITSinjex_,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||||
registerInstance: Function,
|
registerInstance: Function,
|
||||||
|
mode: 'instance' | 'standalone' = 'standalone',
|
||||||
): void {
|
): void {
|
||||||
describe('RegisterInstance Decorator Tests', () => {
|
describe('RegisterInstance Decorator Tests', () => {
|
||||||
let container: ITSinjex;
|
let container: ITSinjex;
|
||||||
@@ -295,7 +296,10 @@ export function test_RegisterInstanceDecorator(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should register an instance of a dependency', () => {
|
it('should register an instance of a dependency', () => {
|
||||||
@registerInstance('InstanceIdentifier')
|
@registerInstance(
|
||||||
|
'InstanceIdentifier',
|
||||||
|
mode === 'instance' ? 'instance' : undefined,
|
||||||
|
)
|
||||||
class TestClass {
|
class TestClass {
|
||||||
private readonly _dependency!: any;
|
private readonly _dependency!: any;
|
||||||
|
|
||||||
@@ -337,7 +341,10 @@ export function test_RegisterInstanceDecorator(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should register an instance of a dependency and get it on set', () => {
|
it('should register an instance of a dependency and get it on set', () => {
|
||||||
@registerInstance('InstanceIdentifier')
|
@registerInstance(
|
||||||
|
'InstanceIdentifier',
|
||||||
|
mode === 'instance' ? 'instance' : undefined,
|
||||||
|
)
|
||||||
class TestClass {
|
class TestClass {
|
||||||
private readonly _dependency!: any;
|
private readonly _dependency!: any;
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable deprecation/deprecation */
|
||||||
import { TSinjex } from 'src/classes/TSinjex';
|
import { TSinjex } from 'src/classes/TSinjex';
|
||||||
import { Inject } from 'src/decorators/Inject';
|
import { Inject } from 'src/decorators/Inject';
|
||||||
import { Register } from 'src/decorators/Register';
|
import { Register } from 'src/decorators/Register';
|
||||||
@@ -13,3 +14,5 @@ test_InjectDecorator(TSinjex, Inject);
|
|||||||
test_RegisterDecorator(TSinjex, Register);
|
test_RegisterDecorator(TSinjex, Register);
|
||||||
|
|
||||||
test_RegisterInstanceDecorator(TSinjex, RegisterInstance);
|
test_RegisterInstanceDecorator(TSinjex, RegisterInstance);
|
||||||
|
|
||||||
|
test_RegisterInstanceDecorator(TSinjex, Register, 'instance');
|
||||||
|
@@ -1,6 +1,134 @@
|
|||||||
|
import { InitDelegate } from 'src/types/InitDelegate';
|
||||||
import { TSinjex } from '../classes/TSinjex';
|
import { TSinjex } from '../classes/TSinjex';
|
||||||
import { Identifier } from '../types/Identifier';
|
import { Identifier } from '../types/Identifier';
|
||||||
|
|
||||||
|
//#region Overloads
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A decorator to register a class in the **TSinjex** DI (Dependency Injection) container.
|
||||||
|
* @template TargetType The type of the class to be registered.
|
||||||
|
* @param identifier The identifier used to register the class in the DI container.
|
||||||
|
* @see {@link Identifier} for more information on identifiers.
|
||||||
|
* @param deprecated If true, the dependency is deprecated and a warning
|
||||||
|
* is logged only once upon the first resolution of the dependency.
|
||||||
|
* @returns The decorator function to be applied on the class.
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* \@Register('MyClassIdentifier')
|
||||||
|
* class MyClass {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* \@Register('MyClassIdentifier', true)
|
||||||
|
* class MyClass {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function Register<
|
||||||
|
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
||||||
|
>(
|
||||||
|
identifier: Identifier,
|
||||||
|
deprecated?: boolean,
|
||||||
|
): (constructor: TargetType, ...args: unknown[]) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
||||||
|
* @template TargetType The type of the class whose instance is to be registered.
|
||||||
|
* @param identifier The identifier used to register the instance in the DI container.
|
||||||
|
* @see {@link Identifier} for more information on identifiers.
|
||||||
|
* @param shouldRegister Set to 'instance' to register the instance in the DI container
|
||||||
|
* with an empty constructor.
|
||||||
|
* @param deprecated If true, the dependency is deprecated and a warning
|
||||||
|
* is logged only once upon the first resolution of the dependency.
|
||||||
|
* @returns The decorator function to be applied on the class.
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* \@RegisterInstance('MyClassInstanceIdentifier', 'instance')
|
||||||
|
* class MyClass {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* \@RegisterInstance('MyClassInstanceIdentifier', 'instance', true)
|
||||||
|
* class MyClass {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function Register<
|
||||||
|
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
||||||
|
>(
|
||||||
|
identifier: Identifier,
|
||||||
|
shouldRegister: 'instance',
|
||||||
|
deprecated?: boolean,
|
||||||
|
): (constructor: TargetType, ...args: unknown[]) => void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
||||||
|
* @template TargetType The type of the class whose instance is to be registered.
|
||||||
|
* @param identifier The identifier used to register the instance in the DI container.
|
||||||
|
* @see {@link Identifier} for more information on identifiers.
|
||||||
|
* @param init An optional initializer function which get the constructor of the class
|
||||||
|
* as input and returns an instance of the class.
|
||||||
|
* @param deprecated If true, the dependency is deprecated and a warning
|
||||||
|
* is logged only once upon the first resolution of the dependency.
|
||||||
|
* @see {@link InitDelegate} for more information on initializer functions.
|
||||||
|
* @returns The decorator function to be applied on the class.
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor())
|
||||||
|
* class MyClass {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor(), true)
|
||||||
|
* class MyClass {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function Register<
|
||||||
|
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
||||||
|
>(
|
||||||
|
identifier: Identifier,
|
||||||
|
init?: InitDelegate<
|
||||||
|
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
||||||
|
InstanceType<TargetType>
|
||||||
|
>,
|
||||||
|
deprecated?: boolean,
|
||||||
|
): (constructor: TargetType, ...args: unknown[]) => void;
|
||||||
|
|
||||||
|
//#endregion Overloads
|
||||||
|
|
||||||
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
||||||
|
export function Register<
|
||||||
|
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
||||||
|
>(
|
||||||
|
identifier: Identifier,
|
||||||
|
arg1?:
|
||||||
|
| undefined
|
||||||
|
| boolean
|
||||||
|
| InitDelegate<TargetType, InstanceType<TargetType>>
|
||||||
|
| 'instance',
|
||||||
|
arg2?: boolean,
|
||||||
|
): (constructor: TargetType, ...args: unknown[]) => void {
|
||||||
|
const deprecated = typeof arg1 === 'boolean' ? arg1 : arg2;
|
||||||
|
const init = typeof arg1 === 'function' ? arg1 : undefined;
|
||||||
|
const shouldRegisterInstance = arg1 === 'instance';
|
||||||
|
|
||||||
|
if (init == undefined && shouldRegisterInstance !== true) {
|
||||||
|
return _register(identifier, deprecated);
|
||||||
|
} else {
|
||||||
|
return _registerInstance(identifier, init, deprecated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A decorator to register a class in the **TSinjex** DI (Dependency Injection) container.
|
* A decorator to register a class in the **TSinjex** DI (Dependency Injection) container.
|
||||||
* @template TargetType The type of the class to be registered.
|
* @template TargetType The type of the class to be registered.
|
||||||
@@ -17,7 +145,7 @@ import { Identifier } from '../types/Identifier';
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function Register<
|
function _register<
|
||||||
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
||||||
>(identifier: Identifier, deprecated?: boolean) {
|
>(identifier: Identifier, deprecated?: boolean) {
|
||||||
return function (constructor: TargetType, ...args: unknown[]): void {
|
return function (constructor: TargetType, ...args: unknown[]): void {
|
||||||
@@ -28,3 +156,111 @@ export function Register<
|
|||||||
diContainer.register(identifier, constructor, deprecated);
|
diContainer.register(identifier, constructor, deprecated);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
||||||
|
* @template TargetType The type of the class whose instance is to be registered.
|
||||||
|
* @param identifier The identifier used to register the instance in the DI container.
|
||||||
|
* @see {@link Identifier} for more information on identifiers.
|
||||||
|
* @param init An optional initializer function which get the constructor of the class
|
||||||
|
* as input and returns an instance of the class.
|
||||||
|
* @param deprecated If true, the dependency is deprecated and a warning
|
||||||
|
* is logged only once upon the first resolution of the dependency.
|
||||||
|
* @see {@link InitDelegate} for more information on initializer functions.
|
||||||
|
* @returns The decorator function to be applied on the class.
|
||||||
|
* @example
|
||||||
|
* ```ts
|
||||||
|
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor())
|
||||||
|
* class MyClass {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
function _registerInstance<
|
||||||
|
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
||||||
|
>(
|
||||||
|
identifier: Identifier,
|
||||||
|
init?: InitDelegate<
|
||||||
|
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
||||||
|
InstanceType<TargetType>
|
||||||
|
>,
|
||||||
|
deprecated?: boolean,
|
||||||
|
) {
|
||||||
|
return function (constructor: TargetType, ...args: unknown[]): void {
|
||||||
|
// Get the instance of the DI container
|
||||||
|
const diContainer = TSinjex.getInstance();
|
||||||
|
let instance: InstanceType<TargetType>;
|
||||||
|
|
||||||
|
// Create a proxy to instantiate the class when needed (Lazy Initialization)
|
||||||
|
let lazyProxy: unknown = new Proxy(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
({ instance, lazyProxy } = initializeInstance<TargetType>(
|
||||||
|
instance,
|
||||||
|
init,
|
||||||
|
constructor,
|
||||||
|
args,
|
||||||
|
lazyProxy,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Return the requested property of the instance
|
||||||
|
return instance[prop as keyof InstanceType<TargetType>];
|
||||||
|
},
|
||||||
|
set(target, prop, value, receiver) {
|
||||||
|
({ instance, lazyProxy } = initializeInstance<TargetType>(
|
||||||
|
instance,
|
||||||
|
init,
|
||||||
|
constructor,
|
||||||
|
args,
|
||||||
|
lazyProxy,
|
||||||
|
));
|
||||||
|
|
||||||
|
// Set the requested property of the instance
|
||||||
|
return (instance[prop as keyof InstanceType<TargetType>] =
|
||||||
|
value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register the lazy proxy in the DI container
|
||||||
|
diContainer.register(identifier, lazyProxy, deprecated);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the instance of the class.
|
||||||
|
* @template TargetType The type of the class whose instance is to be initialized.
|
||||||
|
* @param instance The instance of the class to be initialized.
|
||||||
|
* @param init The optional initializer function to initialize the instance.
|
||||||
|
* @param constructor The constructor of the class.
|
||||||
|
* @param args The arguments to be passed to the constructor of the class.
|
||||||
|
* @param lazyProxy The lazy proxy to instantiate the class when needed.
|
||||||
|
* @returns The initialized instance and the lazy proxy.
|
||||||
|
*/
|
||||||
|
function initializeInstance<
|
||||||
|
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
||||||
|
>(
|
||||||
|
instance: InstanceType<TargetType>,
|
||||||
|
init:
|
||||||
|
| InitDelegate<
|
||||||
|
TargetType &
|
||||||
|
(new (..._args: unknown[]) => InstanceType<TargetType>),
|
||||||
|
InstanceType<TargetType>
|
||||||
|
>
|
||||||
|
| undefined,
|
||||||
|
constructor: TargetType,
|
||||||
|
args: unknown[],
|
||||||
|
lazyProxy: unknown,
|
||||||
|
): { instance: InstanceType<TargetType>; lazyProxy: unknown } {
|
||||||
|
if (instance == null) {
|
||||||
|
if (init) {
|
||||||
|
instance = init(constructor);
|
||||||
|
} else {
|
||||||
|
instance = new constructor(...args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lazyProxy = instance;
|
||||||
|
|
||||||
|
return { instance, lazyProxy };
|
||||||
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
import { TSinjex } from '../classes/TSinjex';
|
import { Register } from './Register';
|
||||||
import { Identifier } from '../types/Identifier';
|
import { Identifier } from '../types/Identifier';
|
||||||
import { InitDelegate } from '../types/InitDelegate';
|
import { InitDelegate } from '../types/InitDelegate';
|
||||||
|
|
||||||
@@ -9,6 +9,8 @@ import { InitDelegate } from '../types/InitDelegate';
|
|||||||
* @see {@link Identifier} for more information on identifiers.
|
* @see {@link Identifier} for more information on identifiers.
|
||||||
* @param init An optional initializer function which get the constructor of the class
|
* @param init An optional initializer function which get the constructor of the class
|
||||||
* as input and returns an instance of the class.
|
* as input and returns an instance of the class.
|
||||||
|
* @param deprecated If true, the dependency is deprecated and a warning
|
||||||
|
* is logged only once upon the first resolution of the dependency.
|
||||||
* @see {@link InitDelegate} for more information on initializer functions.
|
* @see {@link InitDelegate} for more information on initializer functions.
|
||||||
* @returns The decorator function to be applied on the class.
|
* @returns The decorator function to be applied on the class.
|
||||||
* @example
|
* @example
|
||||||
@@ -18,6 +20,7 @@ import { InitDelegate } from '../types/InitDelegate';
|
|||||||
* // ...
|
* // ...
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
|
* @deprecated Use {@link Register} instead. This decorator already uses the {@link Register} decorator internally.
|
||||||
*/
|
*/
|
||||||
export function RegisterInstance<
|
export function RegisterInstance<
|
||||||
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
||||||
@@ -27,47 +30,10 @@ export function RegisterInstance<
|
|||||||
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
||||||
InstanceType<TargetType>
|
InstanceType<TargetType>
|
||||||
>,
|
>,
|
||||||
) {
|
deprecated?: boolean,
|
||||||
return function (constructor: TargetType, ...args: unknown[]): void {
|
): (constructor: TargetType, ...args: unknown[]) => void {
|
||||||
// Get the instance of the DI container
|
const initDelegate = typeof init === 'function' ? init : undefined;
|
||||||
const diContainer = TSinjex.getInstance();
|
|
||||||
let instance: InstanceType<TargetType>;
|
|
||||||
|
|
||||||
// Create a proxy to instantiate the class when needed (Lazy Initialization)
|
if (initDelegate) return Register(identifier, initDelegate, deprecated);
|
||||||
let lazyProxy: unknown = new Proxy(
|
else return Register(identifier, 'instance', deprecated);
|
||||||
{},
|
|
||||||
{
|
|
||||||
get(target, prop, receiver) {
|
|
||||||
if (instance == null) {
|
|
||||||
if (init) {
|
|
||||||
instance = init(constructor);
|
|
||||||
} else {
|
|
||||||
instance = new constructor(...args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lazyProxy = instance;
|
|
||||||
|
|
||||||
// Return the requested property of the instance
|
|
||||||
return instance[prop as keyof InstanceType<TargetType>];
|
|
||||||
},
|
|
||||||
set(target, prop, value, receiver) {
|
|
||||||
if (instance == null) {
|
|
||||||
if (init) {
|
|
||||||
instance = init(constructor);
|
|
||||||
} else {
|
|
||||||
instance = new constructor(...args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lazyProxy = instance;
|
|
||||||
|
|
||||||
// Set the requested property of the instance
|
|
||||||
return (instance[prop as keyof InstanceType<TargetType>] =
|
|
||||||
value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Register the lazy proxy in the DI container
|
|
||||||
diContainer.register(identifier, lazyProxy);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,9 @@ export * from './decorators/Inject';
|
|||||||
export * from './decorators/Register';
|
export * from './decorators/Register';
|
||||||
export * from './decorators/RegisterInstance';
|
export * from './decorators/RegisterInstance';
|
||||||
|
|
||||||
|
// Helper
|
||||||
|
export * from './helper/ImplementsStatic';
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
export * from './functions/resolve';
|
export * from './functions/resolve';
|
||||||
export * from './functions/register';
|
export * from './functions/register';
|
||||||
|
Reference in New Issue
Block a user