@djodjonx/neo-syringe 1.1.5 → 1.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.
- package/.github/workflows/ci.yml +6 -5
- package/.github/workflows/docs.yml +59 -0
- package/CHANGELOG.md +27 -0
- package/README.md +74 -740
- package/dist/{GraphValidator-G0F4QiLk.cjs → GraphValidator-CV4VoJl0.cjs} +18 -10
- package/dist/{GraphValidator-C8ldJtNp.mjs → GraphValidator-DXqqkNdS.mjs} +18 -10
- package/dist/cli/index.cjs +16 -1
- package/dist/cli/index.mjs +16 -1
- package/dist/index.d.cts +31 -5
- package/dist/index.d.mts +31 -5
- package/dist/lsp/index.cjs +1 -1
- package/dist/lsp/index.mjs +1 -1
- package/dist/unplugin/index.cjs +33 -9
- package/dist/unplugin/index.d.cts +7 -5
- package/dist/unplugin/index.d.mts +7 -5
- package/dist/unplugin/index.mjs +33 -9
- package/docs/.vitepress/config.ts +109 -0
- package/docs/.vitepress/theme/custom.css +150 -0
- package/docs/.vitepress/theme/index.ts +17 -0
- package/docs/api/configuration.md +274 -0
- package/docs/api/functions.md +291 -0
- package/docs/api/types.md +158 -0
- package/docs/guide/basic-usage.md +267 -0
- package/docs/guide/cli.md +174 -0
- package/docs/guide/generated-code.md +284 -0
- package/docs/guide/getting-started.md +171 -0
- package/docs/guide/ide-plugin.md +203 -0
- package/docs/guide/injection-types.md +287 -0
- package/docs/guide/legacy-migration.md +333 -0
- package/docs/guide/lifecycle.md +223 -0
- package/docs/guide/parent-container.md +321 -0
- package/docs/guide/scoped-injections.md +271 -0
- package/docs/guide/what-is-neo-syringe.md +162 -0
- package/docs/guide/why-neo-syringe.md +219 -0
- package/docs/index.md +138 -0
- package/docs/public/logo.png +0 -0
- package/package.json +15 -12
- package/src/analyzer/Analyzer.ts +20 -10
- package/src/analyzer/types.ts +55 -49
- package/src/cli/index.ts +15 -0
- package/src/generator/Generator.ts +24 -2
- package/src/generator/GraphValidator.ts +6 -2
- package/src/types.ts +30 -4
- package/src/unplugin/index.ts +13 -41
- package/tests/analyzer/Analyzer.test.ts +4 -4
- package/tests/analyzer/AnalyzerDeclarative.test.ts +1 -1
- package/tests/analyzer/Factory.test.ts +2 -2
- package/tests/analyzer/Scoped.test.ts +434 -0
- package/tests/cli/cli.test.ts +91 -0
- package/tests/e2e/container-integration.test.ts +21 -21
- package/tests/e2e/generated-code.test.ts +7 -7
- package/tests/e2e/scoped.test.ts +370 -0
- package/tests/e2e/snapshots.test.ts +2 -2
- package/tests/e2e/standalone.test.ts +2 -2
- package/tests/generator/ExternalGenerator.test.ts +1 -1
- package/tests/generator/FactoryGenerator.test.ts +6 -6
- package/tests/generator/Generator.test.ts +2 -2
- package/tests/generator/GeneratorDeclarative.test.ts +1 -1
- package/tests/generator/GraphValidator.test.ts +1 -1
- package/tsconfig.json +2 -1
- package/typedoc.json +0 -5
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { defineConfig } from 'vitepress'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
title: 'Neo-Syringe',
|
|
5
|
+
description: 'Zero-Overhead, Compile-Time Dependency Injection for TypeScript',
|
|
6
|
+
|
|
7
|
+
head: [
|
|
8
|
+
['link', { rel: 'icon', href: '/logo.png' }],
|
|
9
|
+
['meta', { name: 'theme-color', content: '#0d9488' }],
|
|
10
|
+
['meta', { property: 'og:type', content: 'website' }],
|
|
11
|
+
['meta', { property: 'og:title', content: 'Neo-Syringe' }],
|
|
12
|
+
['meta', { property: 'og:description', content: 'Zero-Overhead, Compile-Time Dependency Injection for TypeScript' }],
|
|
13
|
+
['meta', { property: 'og:image', content: '/logo.png' }],
|
|
14
|
+
],
|
|
15
|
+
|
|
16
|
+
base: '/neo-syringe/',
|
|
17
|
+
|
|
18
|
+
themeConfig: {
|
|
19
|
+
logo: '/logo.png',
|
|
20
|
+
|
|
21
|
+
nav: [
|
|
22
|
+
{ text: 'Guide', link: '/guide/getting-started' },
|
|
23
|
+
{ text: 'API', link: '/api/types' },
|
|
24
|
+
{
|
|
25
|
+
text: 'Examples',
|
|
26
|
+
items: [
|
|
27
|
+
{ text: 'Basic Usage', link: '/guide/basic-usage' },
|
|
28
|
+
{ text: 'Parent Container', link: '/guide/parent-container' },
|
|
29
|
+
{ text: 'Legacy Migration', link: '/guide/legacy-migration' },
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
text: 'Links',
|
|
34
|
+
items: [
|
|
35
|
+
{ text: 'GitHub', link: 'https://github.com/djodjonx/neo-syringe' },
|
|
36
|
+
{ text: 'NPM', link: 'https://www.npmjs.com/package/@djodjonx/neo-syringe' },
|
|
37
|
+
{ text: 'Changelog', link: 'https://github.com/djodjonx/neo-syringe/blob/main/CHANGELOG.md' },
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
|
|
42
|
+
sidebar: {
|
|
43
|
+
'/guide/': [
|
|
44
|
+
{
|
|
45
|
+
text: 'Introduction',
|
|
46
|
+
items: [
|
|
47
|
+
{ text: 'What is Neo-Syringe?', link: '/guide/what-is-neo-syringe' },
|
|
48
|
+
{ text: 'Getting Started', link: '/guide/getting-started' },
|
|
49
|
+
{ text: 'Why Neo-Syringe?', link: '/guide/why-neo-syringe' },
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
text: 'Core Concepts',
|
|
54
|
+
items: [
|
|
55
|
+
{ text: 'Basic Usage', link: '/guide/basic-usage' },
|
|
56
|
+
{ text: 'Injection Types', link: '/guide/injection-types' },
|
|
57
|
+
{ text: 'Lifecycle', link: '/guide/lifecycle' },
|
|
58
|
+
{ text: 'Scoped Injections', link: '/guide/scoped-injections' },
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
text: 'Advanced',
|
|
63
|
+
items: [
|
|
64
|
+
{ text: 'Parent Container', link: '/guide/parent-container' },
|
|
65
|
+
{ text: 'Legacy Migration', link: '/guide/legacy-migration' },
|
|
66
|
+
{ text: 'Generated Code', link: '/guide/generated-code' },
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
text: 'Tools',
|
|
71
|
+
items: [
|
|
72
|
+
{ text: 'CLI Validator', link: '/guide/cli' },
|
|
73
|
+
{ text: 'IDE Plugin', link: '/guide/ide-plugin' },
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
'/api/': [
|
|
78
|
+
{
|
|
79
|
+
text: 'API Reference',
|
|
80
|
+
items: [
|
|
81
|
+
{ text: 'Types', link: '/api/types' },
|
|
82
|
+
{ text: 'Functions', link: '/api/functions' },
|
|
83
|
+
{ text: 'Configuration', link: '/api/configuration' },
|
|
84
|
+
]
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
socialLinks: [
|
|
90
|
+
{ icon: 'github', link: 'https://github.com/djodjonx/neo-syringe' },
|
|
91
|
+
{ icon: 'npm', link: 'https://www.npmjs.com/package/@djodjonx/neo-syringe' }
|
|
92
|
+
],
|
|
93
|
+
|
|
94
|
+
footer: {
|
|
95
|
+
message: 'Released under the MIT License.',
|
|
96
|
+
copyright: 'Copyright © 2024-present Neo-Syringe Contributors'
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
search: {
|
|
100
|
+
provider: 'local'
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
editLink: {
|
|
104
|
+
pattern: 'https://github.com/djodjonx/neo-syringe/edit/main/docs/:path',
|
|
105
|
+
text: 'Edit this page on GitHub'
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Neo-Syringe Custom Theme
|
|
3
|
+
* Colors: Teal (#0d9488) + Orange (#f97316)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
:root {
|
|
7
|
+
/* Brand Colors */
|
|
8
|
+
--neo-teal: #0d9488;
|
|
9
|
+
--neo-teal-light: #14b8a6;
|
|
10
|
+
--neo-teal-dark: #0f766e;
|
|
11
|
+
--neo-orange: #f97316;
|
|
12
|
+
--neo-orange-light: #fb923c;
|
|
13
|
+
--neo-orange-dark: #ea580c;
|
|
14
|
+
|
|
15
|
+
/* VitePress Color Overrides */
|
|
16
|
+
--vp-c-brand-1: var(--neo-teal);
|
|
17
|
+
--vp-c-brand-2: var(--neo-teal-light);
|
|
18
|
+
--vp-c-brand-3: var(--neo-teal-dark);
|
|
19
|
+
--vp-c-brand-soft: rgba(13, 148, 136, 0.14);
|
|
20
|
+
|
|
21
|
+
/* Accent for highlights */
|
|
22
|
+
--vp-c-tip-1: var(--neo-teal);
|
|
23
|
+
--vp-c-tip-2: var(--neo-teal-light);
|
|
24
|
+
--vp-c-tip-3: var(--neo-teal-dark);
|
|
25
|
+
--vp-c-tip-soft: rgba(13, 148, 136, 0.14);
|
|
26
|
+
|
|
27
|
+
/* Warning with orange */
|
|
28
|
+
--vp-c-warning-1: var(--neo-orange);
|
|
29
|
+
--vp-c-warning-2: var(--neo-orange-light);
|
|
30
|
+
--vp-c-warning-3: var(--neo-orange-dark);
|
|
31
|
+
--vp-c-warning-soft: rgba(249, 115, 22, 0.14);
|
|
32
|
+
|
|
33
|
+
/* Button colors */
|
|
34
|
+
--vp-button-brand-border: transparent;
|
|
35
|
+
--vp-button-brand-text: #fff;
|
|
36
|
+
--vp-button-brand-bg: var(--neo-teal);
|
|
37
|
+
--vp-button-brand-hover-border: transparent;
|
|
38
|
+
--vp-button-brand-hover-text: #fff;
|
|
39
|
+
--vp-button-brand-hover-bg: var(--neo-teal-light);
|
|
40
|
+
--vp-button-brand-active-border: transparent;
|
|
41
|
+
--vp-button-brand-active-text: #fff;
|
|
42
|
+
--vp-button-brand-active-bg: var(--neo-teal-dark);
|
|
43
|
+
|
|
44
|
+
/* Alt button with orange accent */
|
|
45
|
+
--vp-button-alt-border: var(--neo-orange);
|
|
46
|
+
--vp-button-alt-text: var(--neo-orange);
|
|
47
|
+
--vp-button-alt-bg: transparent;
|
|
48
|
+
--vp-button-alt-hover-border: var(--neo-orange-light);
|
|
49
|
+
--vp-button-alt-hover-text: var(--neo-orange-light);
|
|
50
|
+
--vp-button-alt-hover-bg: rgba(249, 115, 22, 0.1);
|
|
51
|
+
|
|
52
|
+
/* Home hero gradient */
|
|
53
|
+
--vp-home-hero-name-color: transparent;
|
|
54
|
+
--vp-home-hero-name-background: linear-gradient(135deg, var(--neo-teal) 0%, var(--neo-orange) 100%);
|
|
55
|
+
|
|
56
|
+
--vp-home-hero-image-background-image: linear-gradient(135deg, rgba(13, 148, 136, 0.3) 0%, rgba(249, 115, 22, 0.3) 100%);
|
|
57
|
+
--vp-home-hero-image-filter: blur(44px);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.dark {
|
|
61
|
+
--vp-c-brand-1: var(--neo-teal-light);
|
|
62
|
+
--vp-c-brand-2: var(--neo-teal);
|
|
63
|
+
--vp-c-brand-3: var(--neo-teal-dark);
|
|
64
|
+
|
|
65
|
+
--vp-home-hero-image-background-image: linear-gradient(135deg, rgba(13, 148, 136, 0.4) 0%, rgba(249, 115, 22, 0.4) 100%);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Hero section enhancements */
|
|
69
|
+
.VPHero .VPImage {
|
|
70
|
+
max-width: 280px;
|
|
71
|
+
max-height: 280px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.VPHero .tagline {
|
|
75
|
+
font-size: 1.25rem !important;
|
|
76
|
+
color: var(--vp-c-text-2);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/* Feature cards */
|
|
80
|
+
.VPFeature {
|
|
81
|
+
border: 1px solid var(--vp-c-divider);
|
|
82
|
+
transition: all 0.3s ease;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.VPFeature:hover {
|
|
86
|
+
border-color: var(--neo-teal);
|
|
87
|
+
box-shadow: 0 4px 20px rgba(13, 148, 136, 0.15);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.VPFeature .icon {
|
|
91
|
+
font-size: 2rem;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* Code blocks */
|
|
95
|
+
.vp-code-group .tabs label.active {
|
|
96
|
+
color: var(--neo-teal);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Custom badges */
|
|
100
|
+
.vp-badge.tip {
|
|
101
|
+
background-color: var(--neo-teal);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.vp-badge.warning {
|
|
105
|
+
background-color: var(--neo-orange);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Navigation active state */
|
|
109
|
+
.VPNavBarMenuLink.active,
|
|
110
|
+
.VPSidebarItem.is-active > .item > .link > .text {
|
|
111
|
+
color: var(--neo-teal) !important;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Custom container styles */
|
|
115
|
+
.custom-block.tip {
|
|
116
|
+
border-color: var(--neo-teal);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.custom-block.warning {
|
|
120
|
+
border-color: var(--neo-orange);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Table styling */
|
|
124
|
+
table {
|
|
125
|
+
border-collapse: collapse;
|
|
126
|
+
width: 100%;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
th {
|
|
130
|
+
background-color: rgba(13, 148, 136, 0.1);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* Gradient text utility */
|
|
134
|
+
.gradient-text {
|
|
135
|
+
background: linear-gradient(135deg, var(--neo-teal) 0%, var(--neo-orange) 100%);
|
|
136
|
+
-webkit-background-clip: text;
|
|
137
|
+
-webkit-text-fill-color: transparent;
|
|
138
|
+
background-clip: text;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* Animation for hero */
|
|
142
|
+
@keyframes float {
|
|
143
|
+
0%, 100% { transform: translateY(0); }
|
|
144
|
+
50% { transform: translateY(-10px); }
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.VPHero .VPImage img {
|
|
148
|
+
animation: float 3s ease-in-out infinite;
|
|
149
|
+
}
|
|
150
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customize VitePress theme with Neo-Syringe colors
|
|
3
|
+
* Primary: Teal/Cyan (#0d9488)
|
|
4
|
+
* Accent: Orange (#f97316)
|
|
5
|
+
*/
|
|
6
|
+
import { h } from 'vue'
|
|
7
|
+
import type { Theme } from 'vitepress'
|
|
8
|
+
import DefaultTheme from 'vitepress/theme'
|
|
9
|
+
import './custom.css'
|
|
10
|
+
|
|
11
|
+
export default {
|
|
12
|
+
extends: DefaultTheme,
|
|
13
|
+
Layout: () => {
|
|
14
|
+
return h(DefaultTheme.Layout, null, {})
|
|
15
|
+
},
|
|
16
|
+
} satisfies Theme
|
|
17
|
+
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Configure Neo-Syringe in your project.
|
|
4
|
+
|
|
5
|
+
## Build Plugin
|
|
6
|
+
|
|
7
|
+
### Vite
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
// vite.config.ts
|
|
11
|
+
import { defineConfig } from 'vite';
|
|
12
|
+
import { neoSyringePlugin } from '@djodjonx/neo-syringe/plugin';
|
|
13
|
+
|
|
14
|
+
export default defineConfig({
|
|
15
|
+
plugins: [neoSyringePlugin.vite()]
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Rollup
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// rollup.config.js
|
|
23
|
+
import { neoSyringePlugin } from '@djodjonx/neo-syringe/plugin';
|
|
24
|
+
|
|
25
|
+
export default {
|
|
26
|
+
input: 'src/main.ts',
|
|
27
|
+
output: {
|
|
28
|
+
file: 'dist/bundle.js',
|
|
29
|
+
format: 'esm'
|
|
30
|
+
},
|
|
31
|
+
plugins: [neoSyringePlugin.rollup()]
|
|
32
|
+
};
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Webpack
|
|
36
|
+
|
|
37
|
+
```javascript
|
|
38
|
+
// webpack.config.js
|
|
39
|
+
const { webpack } = require('@djodjonx/neo-syringe/plugin');
|
|
40
|
+
|
|
41
|
+
module.exports = {
|
|
42
|
+
plugins: [webpack()]
|
|
43
|
+
};
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### esbuild
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// esbuild.config.js
|
|
50
|
+
import { neoSyringePlugin } from '@djodjonx/neo-syringe/plugin';
|
|
51
|
+
import esbuild from 'esbuild';
|
|
52
|
+
|
|
53
|
+
await esbuild.build({
|
|
54
|
+
entryPoints: ['src/main.ts'],
|
|
55
|
+
bundle: true,
|
|
56
|
+
outfile: 'dist/bundle.js',
|
|
57
|
+
plugins: [neoSyringePlugin.esbuild()]
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Rspack
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
// rspack.config.js
|
|
65
|
+
const { rspack } = require('@djodjonx/neo-syringe/plugin');
|
|
66
|
+
|
|
67
|
+
module.exports = {
|
|
68
|
+
plugins: [rspack()]
|
|
69
|
+
};
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## TypeScript LSP Plugin
|
|
73
|
+
|
|
74
|
+
Add to `tsconfig.json` for IDE error detection:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"compilerOptions": {
|
|
79
|
+
"plugins": [
|
|
80
|
+
{ "name": "@djodjonx/neo-syringe/lsp" }
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
::: tip VS Code
|
|
87
|
+
Remember to select "Use Workspace Version" for TypeScript.
|
|
88
|
+
:::
|
|
89
|
+
|
|
90
|
+
## BuilderConfig Options
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
defineBuilderConfig({
|
|
94
|
+
// Container name (for debugging)
|
|
95
|
+
name: 'AppContainer',
|
|
96
|
+
|
|
97
|
+
// List of injections
|
|
98
|
+
injections: [
|
|
99
|
+
{ token: UserService },
|
|
100
|
+
{ token: useInterface<ILogger>(), provider: ConsoleLogger }
|
|
101
|
+
],
|
|
102
|
+
|
|
103
|
+
// Inherit from partial configs
|
|
104
|
+
extends: [loggingPartial, databasePartial],
|
|
105
|
+
|
|
106
|
+
// Parent container (Neo-Syringe or legacy)
|
|
107
|
+
useContainer: parentContainer
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### name
|
|
112
|
+
|
|
113
|
+
Type: `string`
|
|
114
|
+
|
|
115
|
+
Optional. The container name appears in error messages.
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
defineBuilderConfig({
|
|
119
|
+
name: 'UserModule'
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Error: [UserModule] Service not found: XYZ
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### injections
|
|
126
|
+
|
|
127
|
+
Type: `Injection[]`
|
|
128
|
+
|
|
129
|
+
Required. List of services to register.
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
defineBuilderConfig({
|
|
133
|
+
injections: [
|
|
134
|
+
// Class autowiring
|
|
135
|
+
{ token: UserService },
|
|
136
|
+
|
|
137
|
+
// Interface binding
|
|
138
|
+
{ token: useInterface<ILogger>(), provider: ConsoleLogger },
|
|
139
|
+
|
|
140
|
+
// Explicit provider
|
|
141
|
+
{ token: BaseService, provider: ConcreteService },
|
|
142
|
+
|
|
143
|
+
// Factory
|
|
144
|
+
{ token: useInterface<IConfig>(), provider: () => loadConfig() },
|
|
145
|
+
|
|
146
|
+
// Property token
|
|
147
|
+
{ token: useProperty<string>(ApiService, 'apiUrl'), provider: () => 'http://...' },
|
|
148
|
+
|
|
149
|
+
// With lifecycle
|
|
150
|
+
{ token: RequestContext, lifecycle: 'transient' },
|
|
151
|
+
|
|
152
|
+
// Scoped override
|
|
153
|
+
{ token: useInterface<ILogger>(), provider: MockLogger, scoped: true }
|
|
154
|
+
]
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### extends
|
|
159
|
+
|
|
160
|
+
Type: `PartialConfig[]`
|
|
161
|
+
|
|
162
|
+
Optional. Inherit injections from partial configs.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
const loggingPartial = definePartialConfig({
|
|
166
|
+
injections: [
|
|
167
|
+
{ token: useInterface<ILogger>(), provider: ConsoleLogger }
|
|
168
|
+
]
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
defineBuilderConfig({
|
|
172
|
+
extends: [loggingPartial],
|
|
173
|
+
injections: [
|
|
174
|
+
{ token: UserService } // Can use ILogger
|
|
175
|
+
]
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### useContainer
|
|
180
|
+
|
|
181
|
+
Type: `Container | any`
|
|
182
|
+
|
|
183
|
+
Optional. Parent container for delegation.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
// Neo-Syringe parent
|
|
187
|
+
defineBuilderConfig({
|
|
188
|
+
useContainer: sharedKernel,
|
|
189
|
+
injections: [...]
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// Legacy container (tsyringe, etc.)
|
|
193
|
+
const legacy = declareContainerTokens<{...}>(tsyringeContainer);
|
|
194
|
+
defineBuilderConfig({
|
|
195
|
+
useContainer: legacy,
|
|
196
|
+
injections: [...]
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Injection Options
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
interface Injection<T> {
|
|
204
|
+
token: Token<T>;
|
|
205
|
+
provider?: Provider<T>;
|
|
206
|
+
useFactory?: boolean;
|
|
207
|
+
lifecycle?: 'singleton' | 'transient';
|
|
208
|
+
scoped?: boolean;
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### token
|
|
213
|
+
|
|
214
|
+
Type: `Token<T>` (required)
|
|
215
|
+
|
|
216
|
+
What to register. Can be:
|
|
217
|
+
|
|
218
|
+
- Class constructor: `UserService`
|
|
219
|
+
- Interface token: `useInterface<ILogger>()`
|
|
220
|
+
- Property token: `useProperty<string>(ApiService, 'apiUrl')`
|
|
221
|
+
|
|
222
|
+
### provider
|
|
223
|
+
|
|
224
|
+
Type: `Provider<T>`
|
|
225
|
+
|
|
226
|
+
What provides the instance. Can be:
|
|
227
|
+
|
|
228
|
+
- Class constructor: `ConsoleLogger`
|
|
229
|
+
- Factory function: `(container) => new Service()`
|
|
230
|
+
|
|
231
|
+
If omitted, the token itself is used (autowiring).
|
|
232
|
+
|
|
233
|
+
### useFactory
|
|
234
|
+
|
|
235
|
+
Type: `boolean`
|
|
236
|
+
|
|
237
|
+
Force treating the provider as a factory function.
|
|
238
|
+
|
|
239
|
+
```typescript
|
|
240
|
+
// Auto-detected (arrow function)
|
|
241
|
+
{ provider: () => createService() }
|
|
242
|
+
|
|
243
|
+
// Explicit (regular function)
|
|
244
|
+
{ provider: createService, useFactory: true }
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### lifecycle
|
|
248
|
+
|
|
249
|
+
Type: `'singleton' | 'transient'`
|
|
250
|
+
|
|
251
|
+
Default: `'singleton'`
|
|
252
|
+
|
|
253
|
+
How instances are managed.
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
{ token: UserService, lifecycle: 'singleton' } // One instance
|
|
257
|
+
{ token: RequestContext, lifecycle: 'transient' } // New each time
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### scoped
|
|
261
|
+
|
|
262
|
+
Type: `boolean`
|
|
263
|
+
|
|
264
|
+
Default: `false`
|
|
265
|
+
|
|
266
|
+
If `true`, resolve locally instead of delegating to parent.
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
// Override parent's ILogger with local MockLogger
|
|
270
|
+
{ token: useInterface<ILogger>(), provider: MockLogger, scoped: true }
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
See [Scoped Injections](/guide/scoped-injections) for details.
|
|
274
|
+
|