Skip to content

Commit 696b468

Browse files
committed
docs: fix documentation typo
1 parent 9543d24 commit 696b468

21 files changed

+165
-56
lines changed

docs/docs/controllers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ With @@Returns@@ you can document correctly your endpoint to reflect the correct
471471

472472
:::
473473

474-
> See our codesandbox example [here](https://codesandbox.io/embed/tsed-swagger-example-ripfl?fontsize=14&hidenavigation=1&theme=dark)
474+
> See a live example of generics with Swagger documentation in our [interactive demo](https://codesandbox.io/embed/tsed-swagger-example-ripfl?fontsize=14&hidenavigation=1&theme=dark). This demo showcases how to implement and document generic types with proper Swagger/OpenAPI specifications.
475475
476476
### Throw exceptions
477477

docs/docs/custom-providers.md

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,34 @@ There are a lot of scenarios where you might want to bind something directly to
44
For example, any constant values, configuration objects created based on the current environment,
55
external libraries, or pre-calculated values that depend on few other defined providers.
66

7-
Moreover, you are able to override default implementations, e.g. use different classes or make use of various test doubles (for testing purposes) when needed.
7+
Moreover, you are able to override default implementations, e.g. use different classes or make use of various test
8+
doubles (for testing purposes) when needed.
89

910
One essential thing that you should always keep in mind is that Ts.ED uses @@TokenProvider@@ to identify a dependency.
1011

11-
Usually, the auto-generated tokens are equal to classes. If you want to create a custom provider, you'd need to choose a token.
12+
Usually, the auto-generated tokens are equal to classes. If you want to create a custom provider, you'd need to choose a
13+
token.
1214
Mostly, the custom tokens are represented by either plain strings or symbols.
1315

1416
Let's go through the available options.
1517

1618
Custom providers can also use [hooks](/docs/hooks.md) to handle Ts.ED lifecycle events.
1719

20+
For example:
21+
22+
```typescript
23+
import {Injectable} from "@tsed/di";
24+
25+
@Injectable()
26+
class CustomProvider {
27+
async $onInit() {
28+
// Initialize your custom provider
29+
}
30+
}
31+
```
32+
33+
> There is other hooks available like `$onDestroy`, `$afterRoutesInit`, `$beforeRoutesInit`, `$onReady`, see more [here](/docs/hooks.md).
34+
1835
## Register Value
1936

2037
The `useValue` syntax is useful when it comes to either define a constant value, put external library into DI container,
@@ -35,6 +52,26 @@ In order to inject custom provider, we use the @@Inject@@ decorator. This decora
3552
::: warning
3653
When you declare a provider using a Symbol as a token, you must use the same Symbol to @@Inject@@ decorator.
3754
TypeScript set Object as metadata key for the Symbol token.
55+
56+
```typescript
57+
// Define the symbol once and export it
58+
export const MY_SERVICE = Symbol.for("MY_SERVICE");
59+
60+
// Correct usage
61+
@Injectable()
62+
class MyService {
63+
@Inject(MY_SERVICE)
64+
service: MyServiceType;
65+
}
66+
67+
// Incorrect usage - creates a new Symbol
68+
@Injectable()
69+
class MyService {
70+
@Inject()
71+
service: MyServiceType;
72+
}
73+
```
74+
3875
:::
3976

4077
## Register Factory
@@ -46,18 +83,14 @@ It means that factory may accept arguments, that DI will resolve and pass during
4683

4784
<<< @/docs/snippets/providers/custom-provider-use-factory-declaration.ts
4885

49-
In order to inject a custom provider, we use the @@Inject@@ decorator. This decorator takes a single argument - the token.
86+
In order to inject a custom provider, we use the @@Inject@@ decorator. This decorator takes a single argument - the
87+
token.
5088

5189
::: code-group
5290
<<< @/docs/snippets/providers/decorators/custom-provider-use-value-usage.ts [Decorators]
5391
<<< @/docs/snippets/providers/fn/custom-provider-use-value-usage.ts [Functional API]
5492
:::
5593

56-
::: warning
57-
When you declare a provider using a Symbol as a token, you must use the same Symbol to @@Inject@@ decorator.
58-
TypeScript set Object as metadata key for the Symbol token.
59-
:::
60-
6194
## Register Async Factory
6295

6396
The `useAsyncFactory` is a way of creating asynchronous providers dynamically.
@@ -70,28 +103,38 @@ It means that factory may accept arguments, that DI will resolve and pass during
70103
<<< @/docs/snippets/providers/v7/custom-provider-use-async-factory-declaration.ts [Legacy]
71104
:::
72105

73-
In order to inject a custom provider, we use the @@Inject@@ decorator. This decorator takes a single argument - the token.
106+
In order to inject a custom provider, we use the @@Inject@@ decorator. This decorator takes a single argument - the
107+
token.
74108

75109
::: code-group
76110
<<< @/docs/snippets/providers/decorators/custom-provider-use-value-usage.ts [Decorators]
77111
<<< @/docs/snippets/providers/fn/custom-provider-use-value-usage.ts [Functional API]
78112
:::
79113

80-
::: warning
81-
Because async factories are resolved on server loading, the scope of the provider created by useAsyncFactory will always be considered as `SINGLETON`.
82-
:::
114+
::: danger Important Scope Limitation
115+
Because async factories are resolved on server loading, the scope of the provider created by useAsyncFactory will always
116+
be considered as `SINGLETON`.
117+
118+
This means:
119+
120+
- The provider will be instantiated only once
121+
- The same instance will be shared across all injections
122+
- Request-scoped dependencies should not be used in async factories
123+
:::
83124

84125
## Register Class
85126

86-
The `useClass` syntax is similar to register provider via decorator. But it allows you to use different classes per chosen factors.
127+
The `useClass` syntax is similar to register provider via decorator. But it allows you to use different classes per
128+
chosen factors.
87129
For example, you can change the class depending on the environment profile `production` or `development`.
88130

89131
::: code-group
90132
<<< @/docs/snippets/providers/custom-provider-use-class-declaration.ts [v8]
91133
<<< @/docs/snippets/providers/v7/custom-provider-use-class-declaration.ts [Legacy]
92134
:::
93135

94-
In this case, even if any class depends on ConfigService, Ts.ED will inject an instance of the provided class (`ProdConfigService` or `DevConfigService`) instead.
136+
In this case, even if any class depends on ConfigService, Ts.ED will inject an instance of the provided class (
137+
`ProdConfigService` or `DevConfigService`) instead.
95138

96139
::: code-group
97140
<<< @/docs/snippets/providers/decorators/custom-provider-use-class-usage.ts [Decorators]

docs/docs/providers-lazy-loading.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ speed up the bootstrap time for subsequent calls even further (deferred modules
1818

1919
## Usage
2020

21-
To load a provider on-demand, Ts.ED provide decorators @@LazyInject@@ and @@OptionalLazyInject@@. Here is an example
21+
To load a provider on-demand, Ts.ED provides decorators @@LazyInject@@ and @@OptionalLazyInject@@. Here is an example
2222
with a @@PlatformExceptions@@:
2323

2424
::: code-group
@@ -36,7 +36,7 @@ That means, each consecutive call will be very fast and will return a cached ins
3636

3737
:::
3838

39-
Create you own lazy injectable doesn't require special things, just declare a module or an injectable service with default export:
39+
Creating your own lazy injectable does not require special configuration, just declare a module or an injectable service with default export:
4040

4141
::: code-group
4242
<<< @/docs/snippets/providers/decorators/lazy-inject-declaration.ts [Decorators]

docs/docs/providers.md

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ Providers are plain javascript classes and use one of these decorators on top of
2222
<ApiList query="['Injectable', 'Module', 'Service', 'Controller', 'Interceptor', 'Middleware', 'Protocol'].indexOf(symbolName) > -1" />
2323

2424
::: tip
25-
Since v8, you can also use functional API to define your providers using @@injectable@@ function. This function let you
26-
defined your provider without using decorators and let you define your provider in a more functional way.
25+
Since v8, you can also use the functional API to define your providers using the @@injectable@@ function. This function
26+
lets you
27+
define your provider without using decorators and lets you define your provider in a more functional way.
2728

2829
This page will show you how to use both API to define your providers.
2930

@@ -361,7 +362,7 @@ Using @@Opts@@ decorator on a constructor parameter changes the scope of the pro
361362
to `ProviderScope.INSTANCE`.
362363
:::
363364

364-
## Inject many provider
365+
## Inject many providers
365366

366367
This feature simplifies dependency management when working with multiple implementations of the same interface using
367368
type code.
@@ -398,7 +399,8 @@ export class SomeController {
398399

399400
### AutoInjectable <Badge text="7.82.0+" />
400401

401-
The @@AutoInjectable@@ decorator let you create a class using `new` that will automatically inject all dependencies from his
402+
The @@AutoInjectable@@ decorator let you create a class using `new` that will automatically inject all dependencies from
403+
his
402404
constructor signature.
403405

404406
```ts
@@ -421,17 +423,21 @@ const myService = new MyService({
421423
});
422424
```
423425

424-
In this example, we can see that `MyService` is created using `new`. We can give some options to the constructor and the rest of
426+
In this example, we can see that `MyService` is created using `new`. We can give some options to the constructor and the
427+
rest of
425428
the dependencies will be injected automatically.
426429

427430
::: warning
428-
@@AutoInjectable@@ decorator doesn't declare the class as a provider.
431+
@@AutoInjectable@@ decorator only handles dependency injection when using `new`. It doesn't register the class as a
432+
provider in the DI container. If you need the class to be available for injection in other classes, you must still use
433+
@@Injectable@@.
429434
:::
430435

431436
## Interface abstraction
432437

433438
In some cases, you may want to use an interface to abstract the implementation of a service. This is a common pattern in
434-
TypeScript and can be achieved by using the `provide` option in the `@Injectable` decorator or the `injectable().class()` function.
439+
TypeScript and can be achieved by using the `provide` option in the `@Injectable` decorator or the
440+
`injectable().class()` function.
435441

436442
::: code-group
437443
<<< @/docs/snippets/providers/decorators/interface-abstraction-declaration.ts [Decorators]
@@ -468,8 +474,8 @@ it may become a bottleneck for apps running in the **serverless environment**, w
468474

469475
Lazy loading can help decrease bootstrap time by loading only modules required by the specific serverless function
470476
invocation.
471-
In addition, you could also load other modules asynchronously once the serverless function is "warm" to speed-up the
472-
bootstrap time for subsequent calls even further (deferred modules registration).
477+
Additionally, you can load other modules asynchronously once the serverless function is "warm" to speed up the
478+
bootstrap time for subsequent calls (deferred module registration).
473479

474480
You can read more about these techniques [here](/docs/providers-lazy-loading.md).
475481

@@ -491,10 +497,12 @@ using @@Injectable@@, @@OverrideProvider@@ decorators or @@injectable@@ function
491497
492498
## Inject context
493499

494-
The @@Context@@ decorator or @@context@@ function is used to inject the request context into a class or another function.
500+
The @@Context@@ decorator or @@context@@ function is used to inject the request context into a class or another
501+
function.
495502

496503
Context is a special object that contains all the information about the current request.
497-
It can be available in any injectable context, including controllers, services, and interceptors, while the request is being processed.
504+
It can be available in any injectable context, including controllers, services, and interceptors, while the request is
505+
being processed.
498506

499507
Here is an example to get context:
500508

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import {Injectable, Inject} from "@tsed/di";
1+
import {Inject, Injectable} from "@tsed/di";
22
import {ConfigService} from "./ConfigService.js";
33

44
@Injectable()
55
export class MyService {
66
constructor(@Inject(ConfigService) configService: ConfigService) {
7-
console.log(process.env.NODE_ENV, configService); // DevConfigService or ConfigService
7+
// The injected service will be:
8+
// - DevConfigService when NODE_ENV === "development"
9+
// - ConfigService otherwise
10+
const currentConfig = configService.get();
811
}
912
}

docs/docs/snippets/providers/decorators/custom-provider-use-value-usage.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@ import {CONNECTION} from "./connection.js";
33

44
@Injectable()
55
export class MyService {
6-
constructor(@Inject(CONNECTION) connection: CONNECTION) {}
6+
constructor(@Inject(CONNECTION) private connection: CONNECTION) {
7+
}
8+
9+
async getData() {
10+
// Demonstrate typical usage of the injected connection
11+
return this.connection.query("SELECT * FROM example");
12+
}
713
}
814

docs/docs/snippets/providers/decorators/getting-started-server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {Configuration} from "@tsed/di";
2+
// Note: .js extension is required when using ES modules
23
import {CalendarsController} from "./controllers/CalendarsController.js";
34

45
@Configuration({

docs/docs/snippets/providers/decorators/interface-abstraction-usage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ import {RetryPolicy} from "./RetryPolicy.js";
44
@Injectable()
55
export class MyService {
66
constructor(@Inject(RetryPolicy) private readonly retryPolicy: RetryPolicy) {
7-
// an instance of `TokenBucket`
7+
// RetryPolicy will be automatically injected with its implementation (TokenBucket)
88
}
99
}

docs/docs/snippets/providers/decorators/lazy-inject-declaration.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@ import {Module} from "@tsed/di";
55
imports: [] // Use the imports field if you have services to build
66
})
77
export default class MyModule {
8+
private initialized: boolean = false;
89
$onInit() {
9-
// The hook will be called once the module is loaded
10+
// This lifecycle hook is called after the module is loaded
11+
// and all dependencies are resolved.
12+
// Example: Initialize module-specific resources
13+
this.initialized = true;
14+
console.log("MyModule initialized!");
1015
}
1116
}

docs/docs/snippets/providers/decorators/scope-request.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import {Controller, ProviderScope, Scope} from "@tsed/di";
44
@Controller("/")
55
@Scope(ProviderScope.REQUEST)
66
export class MyController {
7+
// Generates a random number between 0 and 100 for each request
78
private rand = Math.random() * 100;
89

910
@Get("/random")
10-
getValue() {
11+
getRequestScopedRandom() {
1112
return this.rand;
1213
}
1314
}

0 commit comments

Comments
 (0)