ts-ioc-container 50.2.0 → 50.2.2

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.
Files changed (2) hide show
  1. package/README.md +24 -48
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -29,16 +29,11 @@ no global container objects.
29
29
  - can inject [lazy dependencies](#lazy)
30
30
  - composable provider and registration pipelines
31
31
  - custom injectors, hooks, and provider behavior
32
- - product behavior covered by executable specs
33
-
34
32
  ## Content
35
33
 
36
34
  - [Setup](#setup)
37
35
  - [Quickstart](#quickstart)
38
36
  - [Cheatsheet](#cheatsheet)
39
- - [Specs-driven workflow](#specs-driven-workflow)
40
- - [Product capability map](#product-capability-map)
41
- - [Acceptance specs](#acceptance-specs)
42
37
  - [tsyringe alternative](https://igorbabkin.github.io/ts-ioc-container/tsyringe-alternative)
43
38
  - [Inversify and Awilix alternative](https://igorbabkin.github.io/ts-ioc-container/inversify-awilix-alternative)
44
39
  - [Recipes](#recipes)
@@ -102,25 +97,39 @@ And `tsconfig.json` should have next options:
102
97
  ## Quickstart
103
98
 
104
99
  ```typescript
105
- import 'reflect-metadata';
106
- import { Container, register, bindTo, singleton } from 'ts-ioc-container';
100
+ import { bindTo, Container, inject, register, Registration as R, singleton, SingleToken } from 'ts-ioc-container';
107
101
 
108
- @register(bindTo('ILogger'), singleton())
109
- class Logger {
102
+ interface ILogger {
103
+ log(message: string): void;
104
+ }
105
+
106
+ const ILoggerToken = new SingleToken<ILogger>('ILogger');
107
+
108
+ @register(bindTo(ILoggerToken), singleton())
109
+ class Logger implements ILogger {
110
110
  log(message: string) {
111
111
  console.log(message);
112
112
  }
113
113
  }
114
114
 
115
115
  class App {
116
- constructor(private logger = container.resolve<Logger>('ILogger')) {}
116
+ constructor(@inject(ILoggerToken) private logger: ILogger) {}
117
117
  start() {
118
118
  this.logger.log('hello');
119
119
  }
120
120
  }
121
121
 
122
- const container = new Container({ tags: ['application'] }).addRegistration(Logger);
123
- container.resolve(App).start();
122
+ describe('Quickstart', function () {
123
+ it('should resolve App with injected Logger', function () {
124
+ const container = new Container({ tags: ['application'] }).addRegistration(R.fromClass(Logger));
125
+
126
+ const app = container.resolve(App);
127
+ app.start();
128
+
129
+ expect(app).toBeInstanceOf(App);
130
+ });
131
+ });
132
+
124
133
  ```
125
134
 
126
135
  ## Cheatsheet
@@ -144,42 +153,6 @@ container.resolve(App).start();
144
153
  > for `R.fromValue(...)` and `R.fromFn(...)` (which have no class to decorate)
145
154
  > or for third-party classes you don't own.
146
155
 
147
- ## Specs-driven workflow
148
-
149
- Public behavior is described as product capabilities before it is implemented.
150
- The repository keeps the same chain visible in specs, tests, docs, and this
151
- README:
152
-
153
- ```text
154
- Business capability -> user story -> acceptance criteria -> executable spec test -> docs and ADRs
155
- ```
156
-
157
- - ADRs in `docs/adr/` explain durable architecture and process decisions.
158
- - Specs in `specs/` describe epics, stories, use cases, and acceptance criteria.
159
- - Acceptance tests in `__tests__/specs/` execute the public contract.
160
- - README examples in `__tests__/readme/` stay executable and are rendered from `.readme.hbs.md`.
161
-
162
- ### Product capability map
163
-
164
- | Capability | User outcome | Spec | Acceptance test |
165
- | ----------------------- | -------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------- |
166
- | Dependency resolution | Resolve dependencies by key, class, token, or constructor injection. | `specs/epics/dependency-resolution.md` | `__tests__/specs/dependency-resolution.spec.ts` |
167
- | Scoped lifecycle | Isolate application, request, transaction, page, or widget lifecycles. | `specs/epics/scoped-lifecycle.md` | `__tests__/specs/scoped-lifecycle.spec.ts` |
168
- | Dependency registration | Describe classes, values, factories, keys, aliases, and scoped services. | `specs/epics/dependency-registration.md` | `__tests__/specs/dependency-registration.spec.ts` |
169
- | Provider behavior | Cache, decorate, delay, restrict, or parameterize dependency creation. | `specs/epics/provider-behavior.md` | `__tests__/specs/provider-behavior.spec.ts` |
170
- | Token-based injection | Make dependency requests explicit, typed, reusable, and composable. | `specs/epics/token-based-injection.md` | `__tests__/specs/token-based-injection.spec.ts` |
171
- | Injector strategies | Support metadata, simple container, proxy, and custom injection styles. | `specs/epics/injector-strategies.md` | `__tests__/specs/injector-strategies.spec.ts` |
172
- | Lifecycle hooks | Run initialization, cleanup, property injection, and custom hook behavior. | `specs/epics/lifecycle-hooks.md` | `__tests__/specs/lifecycle-hooks.spec.ts` |
173
- | Container modules | Package container configuration by feature, environment, or lifecycle. | `specs/epics/container-modules.md` | `__tests__/specs/container-modules.spec.ts` |
174
- | Metadata utilities | Attach labels, tags, and reusable method behavior to application code. | `specs/epics/metadata-utilities.md` | `__tests__/specs/metadata-utilities.spec.ts` |
175
- | Errors and boundaries | Make misconfiguration and unsupported usage diagnosable. | `specs/epics/errors-and-boundaries.md` | `__tests__/specs/errors-and-boundaries.spec.ts` |
176
-
177
- ### Acceptance specs
178
-
179
- Use `pnpm run test:spec` to run only the executable acceptance specs. These
180
- tests are intentionally product-facing; lower-level regression and implementation
181
- tests stay in the feature folders under `__tests__/`.
182
-
183
156
  ## Recipes
184
157
 
185
158
  ### Express/Next handler (per-request scope)
@@ -2603,6 +2576,9 @@ Sometimes you want to register provider with certain key. This is what `key` is
2603
2576
  - by default, key is class name
2604
2577
  - you can assign the same key to different registrations
2605
2578
 
2579
+ > [!TIP]
2580
+ > Prefer `SingleToken<T>` over plain string literals as registration keys. Tokens are type-safe, rename-friendly, and prevent typos that only surface at runtime.
2581
+
2606
2582
  ```typescript
2607
2583
  import {
2608
2584
  bindTo,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "50.2.0",
3
+ "version": "50.2.2",
4
4
  "description": "Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.",
5
5
  "workspaces": [
6
6
  "docs"