@tsed/di 8.18.2 → 8.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/common/decorators/autoInjectable.js +28 -9
- package/lib/esm/common/decorators/constant.js +26 -22
- package/lib/esm/common/decorators/controller.js +40 -20
- package/lib/esm/common/decorators/injectable.js +30 -10
- package/lib/esm/common/decorators/intercept.js +41 -3
- package/lib/esm/common/decorators/interceptor.js +31 -4
- package/lib/esm/common/decorators/module.js +36 -5
- package/lib/esm/common/decorators/opts.js +20 -12
- package/lib/esm/common/decorators/overrideProvider.js +38 -4
- package/lib/esm/common/decorators/scope.js +32 -3
- package/lib/esm/common/decorators/service.js +24 -4
- package/lib/esm/common/decorators/useOpts.js +21 -13
- package/lib/esm/common/decorators/value.js +28 -22
- package/lib/esm/common/domain/Container.js +20 -0
- package/lib/esm/common/domain/ContextLogger.js +21 -0
- package/lib/esm/common/domain/ControllerProvider.js +22 -0
- package/lib/esm/common/domain/DIContext.js +22 -0
- package/lib/esm/common/domain/InjectablePropertyType.js +16 -0
- package/lib/esm/common/domain/LocalsContainer.js +21 -0
- package/lib/esm/common/domain/Provider.js +19 -0
- package/lib/esm/common/domain/ProviderScope.js +25 -0
- package/lib/esm/common/domain/ProviderType.js +25 -0
- package/lib/esm/common/errors/InjectionError.js +24 -0
- package/lib/esm/common/errors/InvalidPropertyTokenError.js +15 -0
- package/lib/esm/common/fn/inject.js +19 -6
- package/lib/esm/common/fn/injectMany.js +24 -6
- package/lib/esm/common/fn/injectable.js +57 -0
- package/lib/esm/common/fn/injector.js +21 -2
- package/lib/esm/common/fn/lazyInject.js +48 -1
- package/lib/esm/common/fn/localsContainer.js +31 -2
- package/lib/esm/common/fn/logger.js +15 -1
- package/lib/esm/common/services/DIConfiguration.js +24 -0
- package/lib/esm/common/services/DILogger.js +23 -0
- package/lib/esm/common/services/InjectorService.js +89 -43
- package/lib/types/common/decorators/autoInjectable.d.ts +31 -10
- package/lib/types/common/decorators/configuration.d.ts +32 -2
- package/lib/types/common/decorators/constant.d.ts +26 -22
- package/lib/types/common/decorators/controller.d.ts +40 -20
- package/lib/types/common/decorators/inject.d.ts +29 -7
- package/lib/types/common/decorators/injectable.d.ts +30 -10
- package/lib/types/common/decorators/intercept.d.ts +41 -3
- package/lib/types/common/decorators/interceptor.d.ts +31 -4
- package/lib/types/common/decorators/lazyInject.d.ts +43 -9
- package/lib/types/common/decorators/module.d.ts +36 -5
- package/lib/types/common/decorators/opts.d.ts +20 -12
- package/lib/types/common/decorators/overrideProvider.d.ts +38 -4
- package/lib/types/common/decorators/scope.d.ts +32 -3
- package/lib/types/common/decorators/service.d.ts +24 -4
- package/lib/types/common/decorators/useOpts.d.ts +21 -13
- package/lib/types/common/decorators/value.d.ts +28 -22
- package/lib/types/common/domain/Container.d.ts +20 -0
- package/lib/types/common/domain/ContextLogger.d.ts +26 -0
- package/lib/types/common/domain/ControllerProvider.d.ts +29 -0
- package/lib/types/common/domain/DIContext.d.ts +27 -0
- package/lib/types/common/domain/InjectablePropertyType.d.ts +16 -0
- package/lib/types/common/domain/LocalsContainer.d.ts +21 -0
- package/lib/types/common/domain/Provider.d.ts +25 -0
- package/lib/types/common/domain/ProviderScope.d.ts +25 -0
- package/lib/types/common/domain/ProviderType.d.ts +25 -0
- package/lib/types/common/errors/InjectionError.d.ts +24 -0
- package/lib/types/common/errors/InvalidPropertyTokenError.d.ts +15 -0
- package/lib/types/common/fn/configuration.d.ts +31 -0
- package/lib/types/common/fn/constant.d.ts +22 -0
- package/lib/types/common/fn/inject.d.ts +19 -6
- package/lib/types/common/fn/injectMany.d.ts +24 -6
- package/lib/types/common/fn/injectable.d.ts +57 -0
- package/lib/types/common/fn/injector.d.ts +21 -2
- package/lib/types/common/fn/lazyInject.d.ts +48 -1
- package/lib/types/common/fn/localsContainer.d.ts +31 -2
- package/lib/types/common/fn/logger.d.ts +15 -1
- package/lib/types/common/fn/refValue.d.ts +15 -6
- package/lib/types/common/interfaces/AlterRunInContext.d.ts +26 -0
- package/lib/types/common/interfaces/DILogger.d.ts +36 -0
- package/lib/types/common/interfaces/DILoggerOptions.d.ts +23 -0
- package/lib/types/common/interfaces/ImportTokenProviderOpts.d.ts +43 -0
- package/lib/types/common/interfaces/InterceptorContext.d.ts +35 -0
- package/lib/types/common/interfaces/InterceptorMethods.d.ts +27 -0
- package/lib/types/common/interfaces/InvokeOptions.d.ts +8 -0
- package/lib/types/common/interfaces/OnDestroy.d.ts +22 -0
- package/lib/types/common/interfaces/OnInit.d.ts +22 -0
- package/lib/types/common/interfaces/ProviderOpts.d.ts +31 -0
- package/lib/types/common/interfaces/ResolvedInvokeOptions.d.ts +9 -0
- package/lib/types/common/interfaces/TokenProvider.d.ts +32 -2
- package/lib/types/common/interfaces/TokenRoute.d.ts +16 -0
- package/lib/types/common/services/DIConfiguration.d.ts +24 -0
- package/lib/types/common/services/DILogger.d.ts +28 -0
- package/lib/types/common/services/InjectorService.d.ts +89 -43
- package/lib/types/node/utils/asyncHookContext.d.ts +0 -1
- package/package.json +6 -6
|
@@ -26,26 +26,45 @@ function resolveAutoInjectableArgs(token, args) {
|
|
|
26
26
|
return list;
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
29
|
+
* Enable automatic dependency injection for a class constructor.
|
|
30
|
+
*
|
|
31
|
+
* Automatically resolves and injects constructor dependencies while preserving
|
|
32
|
+
* the ability to manually pass arguments. Useful for classes that need both
|
|
33
|
+
* automatic DI and manual instantiation flexibility.
|
|
34
|
+
*
|
|
35
|
+
* ### Usage
|
|
30
36
|
*
|
|
31
|
-
* @example
|
|
32
37
|
* ```typescript
|
|
38
|
+
* import {AutoInjectable} from "@tsed/di";
|
|
39
|
+
*
|
|
33
40
|
* @AutoInjectable()
|
|
34
41
|
* class UserService {
|
|
35
42
|
* constructor(
|
|
36
|
-
* private database: Database,
|
|
37
|
-
*
|
|
43
|
+
* private database: Database, // Automatically injected
|
|
44
|
+
* private logger: Logger, // Automatically injected
|
|
45
|
+
* customConfig?: Config // Can be passed manually
|
|
38
46
|
* ) {}
|
|
39
47
|
* }
|
|
48
|
+
*
|
|
49
|
+
* // Automatic injection
|
|
50
|
+
* const service1 = new UserService();
|
|
51
|
+
*
|
|
52
|
+
* // Manual override
|
|
53
|
+
* const service2 = new UserService(customDb, customLogger, {debug: true});
|
|
54
|
+
*
|
|
55
|
+
* // Partial override (remaining deps auto-injected)
|
|
56
|
+
* const service3 = new UserService(undefined, undefined, {debug: true});
|
|
40
57
|
* ```
|
|
41
58
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* - Automatically resolves
|
|
45
|
-
* -
|
|
59
|
+
* ### Behavior
|
|
60
|
+
*
|
|
61
|
+
* - Automatically resolves dependencies based on TypeScript metadata
|
|
62
|
+
* - Manual arguments override automatic injection for that position
|
|
63
|
+
* - `undefined` arguments trigger automatic injection
|
|
46
64
|
*
|
|
65
|
+
* @returns Class decorator function
|
|
66
|
+
* @public
|
|
47
67
|
* @decorator
|
|
48
|
-
* @returns {ClassDecorator} A class decorator that enables automatic dependency injection
|
|
49
68
|
*/
|
|
50
69
|
export function AutoInjectable() {
|
|
51
70
|
return (constr) => {
|
|
@@ -24,39 +24,43 @@ export function bindConstant(target, propertyKey, expression, defaultValue) {
|
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
|
-
*
|
|
27
|
+
* Inject a frozen configuration value into a property.
|
|
28
28
|
*
|
|
29
|
-
*
|
|
29
|
+
* Retrieves a value from the injector configuration and freezes it (creates an immutable deep clone).
|
|
30
|
+
* The value is lazily loaded on first access and cached for subsequent accesses.
|
|
30
31
|
*
|
|
31
|
-
*
|
|
32
|
-
* import {Env} from "@tsed/core/domain/Env.js";
|
|
33
|
-
* import {Constant, Value} from "@tsed/di";
|
|
32
|
+
* ### Usage
|
|
34
33
|
*
|
|
35
|
-
*
|
|
34
|
+
* ```typescript
|
|
35
|
+
* import {Injectable, Constant} from "@tsed/di";
|
|
36
|
+
* import {Env} from "@tsed/core";
|
|
36
37
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
38
|
+
* @Injectable()
|
|
39
|
+
* export class MyService {
|
|
40
|
+
* @Constant("env")
|
|
41
|
+
* env: Env;
|
|
39
42
|
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
43
|
+
* @Constant("api.baseUrl")
|
|
44
|
+
* apiUrl: string;
|
|
42
45
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
46
|
+
* @Constant("api.timeout", 5000)
|
|
47
|
+
* timeout: number;
|
|
45
48
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
+
* constructor() {
|
|
50
|
+
* // Not available yet - undefined
|
|
51
|
+
* }
|
|
49
52
|
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
+
* $onInit() {
|
|
54
|
+
* console.log(this.env); // Value is available
|
|
55
|
+
* }
|
|
53
56
|
* }
|
|
54
57
|
* ```
|
|
55
58
|
*
|
|
56
|
-
* @
|
|
57
|
-
* @param
|
|
58
|
-
* @
|
|
59
|
-
* @decorator
|
|
59
|
+
* @typeParam Type The expected type of the constant value
|
|
60
|
+
* @param expression Dot-notation path to the configuration value
|
|
61
|
+
* @param defaultValue Optional default value if not found
|
|
62
|
+
* @returns Property decorator function
|
|
63
|
+
* @public
|
|
60
64
|
*/
|
|
61
65
|
export function Constant(expression, defaultValue) {
|
|
62
66
|
return (target, propertyKey) => {
|
|
@@ -12,32 +12,52 @@ function mapOptions(options) {
|
|
|
12
12
|
return options;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Declare a
|
|
16
|
-
* This routing listing will be built with the `express.Router` object.
|
|
15
|
+
* Declare a REST controller with a base path for routing.
|
|
17
16
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
17
|
+
* Registers a class as a controller provider that handles HTTP requests.
|
|
18
|
+
* Annotated methods define routes relative to the controller's base path.
|
|
19
|
+
*
|
|
20
|
+
* ### Usage
|
|
21
21
|
*
|
|
22
22
|
* ```typescript
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
23
|
+
* import {Controller, Get} from "@tsed/di";
|
|
24
|
+
*
|
|
25
|
+
* @Controller("/calendars")
|
|
26
|
+
* export class CalendarCtrl {
|
|
27
|
+
* @Get("/:id")
|
|
28
|
+
* get(@PathParams("id") id: string) {
|
|
29
|
+
* return {id};
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
*
|
|
33
|
+
* // With middleware
|
|
34
|
+
* @Controller({
|
|
35
|
+
* path: "/users",
|
|
36
|
+
* middlewares: {
|
|
37
|
+
* useBefore: [AuthMiddleware]
|
|
38
|
+
* }
|
|
39
|
+
* })
|
|
40
|
+
* export class UserCtrl {}
|
|
41
|
+
*
|
|
42
|
+
* // Nested controllers
|
|
43
|
+
* @Controller({
|
|
44
|
+
* path: "/admin",
|
|
45
|
+
* children: [UserAdminCtrl, ProductAdminCtrl]
|
|
46
|
+
* })
|
|
47
|
+
* export class AdminCtrl {}
|
|
35
48
|
* ```
|
|
36
49
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
50
|
+
* ### Options
|
|
51
|
+
*
|
|
52
|
+
* - `path`: Base route path (string, RegExp, or array)
|
|
53
|
+
* - `children`: Child controller classes for nested routing
|
|
54
|
+
* - `middlewares`: Middleware configuration (useBefore, use, useAfter)
|
|
55
|
+
* - Additional `ProviderOpts` options
|
|
56
|
+
*
|
|
57
|
+
* @param options Controller path or configuration object
|
|
58
|
+
* @returns Class decorator function
|
|
59
|
+
* @public
|
|
39
60
|
* @decorator
|
|
40
|
-
* @classDecorator
|
|
41
61
|
*/
|
|
42
62
|
export function Controller(options) {
|
|
43
63
|
const { children = [], path, ...opts } = mapOptions(options);
|
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
import { injectable } from "../fn/injectable.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* All classes annotated with `@Injectable()` are built one time, excepted if you change the default provider configuration.
|
|
3
|
+
* Declare a class as an injectable provider in the DI system.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Registers a class as a provider that can be injected into other services, controllers, or interceptors.
|
|
6
|
+
* By default, providers are singleton-scoped and built once during application initialization.
|
|
7
|
+
*
|
|
8
|
+
* ### Usage
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import {Injectable} from "@tsed/di";
|
|
12
|
+
*
|
|
13
|
+
* @Injectable()
|
|
14
|
+
* export class MyService {
|
|
15
|
+
* getData() {
|
|
16
|
+
* return "data";
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* // With options
|
|
21
|
+
* @Injectable({
|
|
22
|
+
* scope: ProviderScope.REQUEST,
|
|
23
|
+
* type: ProviderType.PROVIDER
|
|
24
|
+
* })
|
|
25
|
+
* export class RequestScopedService {}
|
|
26
|
+
* ```
|
|
9
27
|
*
|
|
10
28
|
* ### Options
|
|
11
29
|
*
|
|
12
|
-
* - type
|
|
13
|
-
* - scope
|
|
14
|
-
* - token
|
|
15
|
-
* - deps
|
|
30
|
+
* - `type`: Provider category (default: `ProviderType.PROVIDER`)
|
|
31
|
+
* - `scope`: Instance lifecycle scope (default: `ProviderScope.SINGLETON`)
|
|
32
|
+
* - `token`: Custom injection token (overrides class reference)
|
|
33
|
+
* - `deps`: Explicit constructor dependencies (overrides TypeScript metadata)
|
|
16
34
|
*
|
|
17
|
-
* @
|
|
35
|
+
* @param options Provider configuration options
|
|
36
|
+
* @returns Class decorator function
|
|
37
|
+
* @public
|
|
18
38
|
* @decorator
|
|
19
39
|
*/
|
|
20
40
|
export function Injectable(options = {}) {
|
|
@@ -44,10 +44,48 @@ export function bindIntercept(target, propertyKey, token, options) {
|
|
|
44
44
|
return descriptor;
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
|
-
*
|
|
47
|
+
* Apply an interceptor to a method or all methods of a class.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
49
|
+
* Wraps method execution with interceptor logic for cross-cutting concerns like logging,
|
|
50
|
+
* validation, caching, or error handling. Can be applied to individual methods or entire classes.
|
|
51
|
+
*
|
|
52
|
+
* ### Usage
|
|
53
|
+
*
|
|
54
|
+
* ```typescript
|
|
55
|
+
* import {Injectable, Intercept, Interceptor, InterceptorContext, InterceptorMethods} from "@tsed/di";
|
|
56
|
+
*
|
|
57
|
+
* @Interceptor()
|
|
58
|
+
* class LogInterceptor implements InterceptorMethods {
|
|
59
|
+
* intercept(context: InterceptorContext) {
|
|
60
|
+
* console.log("Before:", context.propertyKey);
|
|
61
|
+
* const result = context.next();
|
|
62
|
+
* console.log("After:", result);
|
|
63
|
+
* return result;
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
*
|
|
67
|
+
* @Injectable()
|
|
68
|
+
* class UserService {
|
|
69
|
+
* @Intercept(LogInterceptor)
|
|
70
|
+
* async findById(id: string) {
|
|
71
|
+
* return {id, name: "User"};
|
|
72
|
+
* }
|
|
73
|
+
* }
|
|
74
|
+
*
|
|
75
|
+
* // Apply to all methods
|
|
76
|
+
* @Injectable()
|
|
77
|
+
* @Intercept(LogInterceptor)
|
|
78
|
+
* class ProductService {
|
|
79
|
+
* getAll() {}
|
|
80
|
+
* getById(id: string) {}
|
|
81
|
+
* }
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @typeParam T The interceptor class type
|
|
85
|
+
* @param interceptor The interceptor class token
|
|
86
|
+
* @param options Optional configuration passed to the interceptor
|
|
87
|
+
* @returns Method or class decorator function
|
|
88
|
+
* @public
|
|
51
89
|
* @decorator
|
|
52
90
|
*/
|
|
53
91
|
export function Intercept(interceptor, options) {
|
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
import { interceptor } from "../fn/injectable.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* All services annotated with `@Interceptor()` are constructed one time.
|
|
3
|
+
* Declare an interceptor class for cross-cutting concerns.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
* Registers a class as an interceptor provider that can modify method execution behavior.
|
|
6
|
+
* Interceptors must implement the `InterceptorMethods` interface.
|
|
7
|
+
* All interceptors are singleton-scoped and constructed once.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
+
* ### Usage
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import {Interceptor, InterceptorContext, InterceptorMethods} from "@tsed/di";
|
|
13
|
+
*
|
|
14
|
+
* @Interceptor()
|
|
15
|
+
* export class LogInterceptor implements InterceptorMethods {
|
|
16
|
+
* intercept(context: InterceptorContext) {
|
|
17
|
+
* console.log("Before:", context.propertyKey);
|
|
18
|
+
* const result = context.next();
|
|
19
|
+
* console.log("After:", result);
|
|
20
|
+
* return result;
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
*
|
|
24
|
+
* // Use with @Intercept decorator
|
|
25
|
+
* @Injectable()
|
|
26
|
+
* class MyService {
|
|
27
|
+
* @Intercept(LogInterceptor)
|
|
28
|
+
* async fetchData() {
|
|
29
|
+
* return "data";
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @returns Class decorator function
|
|
35
|
+
* @public
|
|
9
36
|
* @decorator
|
|
10
37
|
*/
|
|
11
38
|
export function Interceptor() {
|
|
@@ -4,13 +4,44 @@ import { ProviderType } from "../domain/ProviderType.js";
|
|
|
4
4
|
import { Configuration } from "./configuration.js";
|
|
5
5
|
import { Injectable } from "./injectable.js";
|
|
6
6
|
/**
|
|
7
|
-
* Declare a
|
|
7
|
+
* Declare a Ts.ED module to organize related providers and configuration.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - deps: List of provider must be injected to the module constructor (explicit declaration)
|
|
9
|
+
* Modules group related functionality together, manage provider dependencies,
|
|
10
|
+
* and configure application settings. They are singleton-scoped by default.
|
|
12
11
|
*
|
|
13
|
-
*
|
|
12
|
+
* ### Usage
|
|
13
|
+
*
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import {Module} from "@tsed/di";
|
|
16
|
+
*
|
|
17
|
+
* @Module({
|
|
18
|
+
* imports: [DatabaseService, CacheService],
|
|
19
|
+
* mount: {
|
|
20
|
+
* "/api": [UserController, ProductController]
|
|
21
|
+
* }
|
|
22
|
+
* })
|
|
23
|
+
* export class AppModule {
|
|
24
|
+
* constructor(private db: DatabaseService) {
|
|
25
|
+
* // Dependencies injected
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* $onInit() {
|
|
29
|
+
* this.db.connect();
|
|
30
|
+
* }
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* ### Options
|
|
35
|
+
*
|
|
36
|
+
* - `imports`: Providers to initialize before this module
|
|
37
|
+
* - `deps`: Constructor dependencies (explicit declaration)
|
|
38
|
+
* - `mount`: Route mappings for controllers
|
|
39
|
+
* - `scope`: Provider scope (default: singleton)
|
|
40
|
+
* - Additional properties are stored as module configuration
|
|
41
|
+
*
|
|
42
|
+
* @param options Module configuration options
|
|
43
|
+
* @returns Class decorator function
|
|
44
|
+
* @public
|
|
14
45
|
* @decorator
|
|
15
46
|
*/
|
|
16
47
|
export function Module(options = {}) {
|
|
@@ -4,7 +4,12 @@ import { ProviderScope } from "../domain/ProviderScope.js";
|
|
|
4
4
|
import { Inject } from "./inject.js";
|
|
5
5
|
import { Scope } from "./scope.js";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Inject custom options passed to a provider instance.
|
|
8
|
+
*
|
|
9
|
+
* Used in configurable providers to receive options from the injection context.
|
|
10
|
+
* Automatically changes the provider scope to `INSTANCE` since each invocation may have different options.
|
|
11
|
+
*
|
|
12
|
+
* ### Usage
|
|
8
13
|
*
|
|
9
14
|
* ```typescript
|
|
10
15
|
* import {Injectable, Opts, UseOpts} from "@tsed/di";
|
|
@@ -12,35 +17,38 @@ import { Scope } from "./scope.js";
|
|
|
12
17
|
* @Injectable()
|
|
13
18
|
* class MyConfigurableService {
|
|
14
19
|
* source: string;
|
|
15
|
-
* constructor(@Opts options: any = {}) {
|
|
16
|
-
* console.log("Hello ", options.source); // log: Hello Service1 then Hello Service2
|
|
17
20
|
*
|
|
18
|
-
*
|
|
21
|
+
* constructor(@Opts options: any = {}) {
|
|
22
|
+
* console.log("Hello", options.source);
|
|
23
|
+
* this.source = options.source;
|
|
19
24
|
* }
|
|
20
25
|
* }
|
|
21
26
|
*
|
|
22
27
|
* @Injectable()
|
|
23
28
|
* class MyService1 {
|
|
24
29
|
* constructor(@UseOpts({source: 'Service1'}) service: MyConfigurableService) {
|
|
25
|
-
* console.log(service.source) //
|
|
30
|
+
* console.log(service.source); // "Service1"
|
|
26
31
|
* }
|
|
27
32
|
* }
|
|
28
33
|
*
|
|
29
34
|
* @Injectable()
|
|
30
35
|
* class MyService2 {
|
|
31
36
|
* constructor(@UseOpts({source: 'Service2'}) service: MyConfigurableService) {
|
|
32
|
-
* console.log(service.source) //
|
|
37
|
+
* console.log(service.source); // "Service2"
|
|
33
38
|
* }
|
|
34
39
|
* }
|
|
35
40
|
* ```
|
|
36
41
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
42
|
+
* ### Warning
|
|
43
|
+
*
|
|
44
|
+
* Using `@Opts` changes the provider scope to `ProviderScope.INSTANCE`,
|
|
45
|
+
* meaning a new instance is created for each injection.
|
|
40
46
|
*
|
|
41
|
-
* @param target
|
|
42
|
-
* @param propertyKey
|
|
43
|
-
* @param index
|
|
47
|
+
* @param target The target class
|
|
48
|
+
* @param propertyKey The constructor method name
|
|
49
|
+
* @param index The parameter index
|
|
50
|
+
* @returns Parameter decorator
|
|
51
|
+
* @public
|
|
44
52
|
* @decorator
|
|
45
53
|
*/
|
|
46
54
|
export function Opts(target, propertyKey, index) {
|
|
@@ -1,9 +1,43 @@
|
|
|
1
1
|
import { GlobalProviders } from "../registries/GlobalProviders.js";
|
|
2
2
|
/**
|
|
3
|
-
* Override
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
3
|
+
* Override an existing provider registration with a new implementation.
|
|
4
|
+
*
|
|
5
|
+
* Replaces the implementation class of a registered provider while keeping the same token.
|
|
6
|
+
* Useful for testing, plugin systems, or providing alternative implementations.
|
|
7
|
+
*
|
|
8
|
+
* ### Usage
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import {Injectable, OverrideProvider} from "@tsed/di";
|
|
12
|
+
*
|
|
13
|
+
* @Injectable()
|
|
14
|
+
* class OriginalService {
|
|
15
|
+
* getData() {
|
|
16
|
+
* return "original";
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* // Override with new implementation
|
|
21
|
+
* @OverrideProvider(OriginalService)
|
|
22
|
+
* class MockService {
|
|
23
|
+
* getData() {
|
|
24
|
+
* return "mocked";
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* // Injected instances will now use MockService
|
|
29
|
+
* @Injectable()
|
|
30
|
+
* class UserService {
|
|
31
|
+
* constructor(private service: OriginalService) {
|
|
32
|
+
* console.log(this.service.getData()); // "mocked"
|
|
33
|
+
* }
|
|
34
|
+
* }
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @param originalProvider The provider class to override
|
|
38
|
+
* @returns Class decorator function
|
|
39
|
+
* @public
|
|
40
|
+
* @decorator
|
|
7
41
|
*/
|
|
8
42
|
export function OverrideProvider(originalProvider) {
|
|
9
43
|
return (target) => {
|
|
@@ -1,10 +1,39 @@
|
|
|
1
1
|
import { StoreSet } from "@tsed/core/decorators/storeSet.js";
|
|
2
2
|
import { ProviderScope } from "../domain/ProviderScope.js";
|
|
3
3
|
/**
|
|
4
|
+
* Define the lifecycle scope of a provider.
|
|
4
5
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Controls when and how provider instances are created and shared.
|
|
7
|
+
* Can be combined with `@Injectable()`, `@Service()`, or other provider decorators.
|
|
8
|
+
*
|
|
9
|
+
* ### Scopes
|
|
10
|
+
*
|
|
11
|
+
* - `SINGLETON`: One instance shared across the application (default)
|
|
12
|
+
* - `REQUEST`: New instance per request/context
|
|
13
|
+
* - `INSTANCE`: New instance on every injection
|
|
14
|
+
*
|
|
15
|
+
* ### Usage
|
|
16
|
+
*
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import {Injectable, Scope, ProviderScope} from "@tsed/di";
|
|
19
|
+
*
|
|
20
|
+
* @Injectable()
|
|
21
|
+
* @Scope(ProviderScope.REQUEST)
|
|
22
|
+
* export class RequestScopedService {
|
|
23
|
+
* // New instance created for each request
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* @Injectable()
|
|
27
|
+
* @Scope("singleton")
|
|
28
|
+
* export class SingletonService {
|
|
29
|
+
* // Same instance shared across the app
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* @param scope The provider scope to set (default: REQUEST)
|
|
34
|
+
* @returns Class decorator function
|
|
35
|
+
* @public
|
|
36
|
+
* @decorator
|
|
8
37
|
*/
|
|
9
38
|
export function Scope(scope = ProviderScope.REQUEST) {
|
|
10
39
|
return StoreSet("scope", scope);
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import { Injectable } from "./injectable.js";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
* All services annotated with `@Service()` are constructed one time.
|
|
3
|
+
* Declare a service class that can be injected into other components.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
* Alias for `@Injectable()` decorator with default settings.
|
|
6
|
+
* Services are singleton-scoped and instantiated once during application startup.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* ### Usage
|
|
9
|
+
*
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import {Service} from "@tsed/di";
|
|
12
|
+
*
|
|
13
|
+
* @Service()
|
|
14
|
+
* export class UserService {
|
|
15
|
+
* async findById(id: string) {
|
|
16
|
+
* // Service logic
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
*
|
|
20
|
+
* // Use in another service or controller
|
|
21
|
+
* @Service()
|
|
22
|
+
* export class AuthService {
|
|
23
|
+
* constructor(private userService: UserService) {}
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @returns Class decorator function
|
|
28
|
+
* @public
|
|
9
29
|
* @decorator
|
|
10
30
|
*/
|
|
11
31
|
export function Service() {
|
|
@@ -4,7 +4,12 @@ import { Store } from "@tsed/core/types/Store.js";
|
|
|
4
4
|
import { decoratorTypeOf } from "@tsed/core/utils/decoratorTypeOf.js";
|
|
5
5
|
import { DI_USE_OPTIONS, DI_USE_PARAM_OPTIONS } from "../constants/constants.js";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Pass custom options to an injected provider.
|
|
8
|
+
*
|
|
9
|
+
* Supplies configuration options when injecting a provider that accepts `@Opts`.
|
|
10
|
+
* Works with constructor parameters and property injection.
|
|
11
|
+
*
|
|
12
|
+
* ### Usage
|
|
8
13
|
*
|
|
9
14
|
* ```typescript
|
|
10
15
|
* import {Injectable, Opts, UseOpts} from "@tsed/di";
|
|
@@ -12,35 +17,38 @@ import { DI_USE_OPTIONS, DI_USE_PARAM_OPTIONS } from "../constants/constants.js"
|
|
|
12
17
|
* @Injectable()
|
|
13
18
|
* class MyConfigurableService {
|
|
14
19
|
* source: string;
|
|
15
|
-
* constructor(@Opts options: any = {}) {
|
|
16
|
-
* console.log("Hello ", options.source); // log: Hello Service1 then Hello Service2
|
|
17
20
|
*
|
|
18
|
-
*
|
|
21
|
+
* constructor(@Opts options: any = {}) {
|
|
22
|
+
* this.source = options.source;
|
|
19
23
|
* }
|
|
20
24
|
* }
|
|
21
25
|
*
|
|
22
26
|
* @Injectable()
|
|
23
27
|
* class MyService1 {
|
|
28
|
+
* // Constructor parameter with options
|
|
24
29
|
* constructor(@UseOpts({source: 'Service1'}) service: MyConfigurableService) {
|
|
25
|
-
* console.log(service.source) //
|
|
30
|
+
* console.log(service.source); // "Service1"
|
|
26
31
|
* }
|
|
27
32
|
* }
|
|
28
33
|
*
|
|
29
34
|
* @Injectable()
|
|
30
35
|
* class MyService2 {
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* }
|
|
36
|
+
* // Property injection with options
|
|
37
|
+
* @Inject(MyConfigurableService)
|
|
38
|
+
* @UseOpts({source: 'Service2'})
|
|
39
|
+
* service: MyConfigurableService;
|
|
34
40
|
* }
|
|
35
41
|
* ```
|
|
36
42
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
43
|
+
* ### Warning
|
|
44
|
+
*
|
|
45
|
+
* The injected provider must use `@Opts` to receive these options.
|
|
46
|
+
* Using `@Opts` automatically sets the provider scope to `INSTANCE`.
|
|
40
47
|
*
|
|
41
|
-
* @
|
|
48
|
+
* @param options Configuration object to pass to the provider
|
|
49
|
+
* @returns Decorator function (parameter or property)
|
|
50
|
+
* @public
|
|
42
51
|
* @decorator
|
|
43
|
-
* @param options
|
|
44
52
|
*/
|
|
45
53
|
export function UseOpts(options) {
|
|
46
54
|
return (target, propertyKey, index) => {
|