Skip to content

Commit e257e0e

Browse files
committed
fix: barry quick fix, 2025-06-06 23:13:14
1 parent 709028f commit e257e0e

File tree

3 files changed

+491
-20
lines changed

3 files changed

+491
-20
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,24 @@ All notable changes to this project will be documented in this file.
1515
- Provider type information
1616
- Error source location
1717
- Dependency chain information
18+
- **Comprehensive Interface Documentation**: Added detailed type support comments to all public and internal interfaces
19+
- Provider interface methods now include detailed type support information
20+
- Injector interface methods document supported injection patterns
21+
- Container interface methods specify supported types and error conditions
22+
- Public API functions include comprehensive usage examples and type constraints
1823

1924
### Technical Details
2025
- Modified `FuncProvider` struct to include `hasError` field
2126
- Updated `NewFuncProvider` to validate error return types
2227
- Enhanced `Invoke` method to handle error checking and propagation
2328
- Maintained backward compatibility with existing provider functions
2429

30+
### Documentation
31+
- Enhanced interface documentation in `dixinternal/interfaces.go` with detailed type support information
32+
- Improved public API documentation in `dix.go` with comprehensive examples and usage patterns
33+
- Added detailed comments for Provider, Injector, Container, and Dependency interfaces
34+
- Documented supported and unsupported types for better developer experience
35+
2536
### Examples
2637
- Added comprehensive provider error handling examples in `example/provider-error/`
2738
- Added correct type usage examples in `example/provider-error-correct/`

dix.go

Lines changed: 197 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package dix
22

33
import (
4-
"reflect"
5-
64
"github.com/pubgo/dix/dixinternal"
75
"github.com/pubgo/funk/assert"
86
)
@@ -28,41 +26,220 @@ func New(opts ...Option) Container {
2826
return dixinternal.New(opts...)
2927
}
3028

31-
// Inject 执行依赖注入
29+
// Inject 注入函数
3230
//
33-
// container: 依赖注入容器
34-
// target: 注入目标 <*struct> 或 <func>
35-
// opts: 可选配置
36-
func Inject[T any](container Container, target T, opts ...Option) T {
37-
vp := reflect.ValueOf(target)
38-
if vp.Kind() == reflect.Struct {
39-
assert.Must(container.Inject(&target, opts...))
40-
} else {
41-
assert.Must(container.Inject(target, opts...))
42-
}
43-
return target
31+
// 解析函数参数并调用函数。
32+
// 通常用于启动函数或回调函数的依赖注入。
33+
//
34+
// 参数:
35+
// - container: 依赖注入容器
36+
// - fn: 目标函数,必须是函数类型
37+
// - opts: 注入选项(可选)
38+
//
39+
// 函数注入规则:
40+
// - 函数只能有入参,不能有出参
41+
// - 函数参数类型必须在容器中已注册
42+
// - 支持的参数类型:
43+
// - 指针类型:*T
44+
// - 接口类型:interface{}
45+
// - 结构体类型:struct{}
46+
// - 切片类型:[]T(注入所有匹配的实例)
47+
// - 映射类型:map[string]T(注入带名称的实例)
48+
// - 不支持基本类型参数:string, int, bool 等
49+
// - 支持可变参数:func(handlers ...Handler)
50+
//
51+
// 函数限制:
52+
// - 函数不能有返回值(包括 error)
53+
// - 函数参数不能是基本类型
54+
//
55+
// 错误处理:
56+
// - 参数解析失败时返回详细错误信息
57+
// - 函数调用 panic 会被捕获并转换为错误
58+
// - 如果函数有返回值,注册时会被拒绝
59+
//
60+
// 示例:
61+
//
62+
// // 有效的启动函数
63+
// func StartServer(logger Logger, db *Database, handlers []Handler) {
64+
// // 使用注入的依赖启动服务器
65+
// }
66+
//
67+
// // 有效的回调函数
68+
// func ProcessRequest(ctx Context, service *UserService) {
69+
// // 处理请求
70+
// }
71+
//
72+
// // 无效的函数(有返回值)
73+
// func InvalidFunc(logger Logger) error {
74+
// return nil // 不允许有返回值
75+
// }
76+
//
77+
// // 无效的函数(基本类型参数)
78+
// func InvalidFunc2(name string, port int) {
79+
// // 不允许基本类型参数
80+
// }
81+
//
82+
// // 使用示例
83+
// container := dix.New()
84+
// container.Provide(NewLogger)
85+
// container.Provide(NewDatabase)
86+
// container.Provide(NewUserService)
87+
//
88+
// // 注入并调用启动函数
89+
// err := dix.Inject(container, StartServer)
90+
// if err != nil {
91+
// log.Fatal(err)
92+
// }
93+
func Inject(container Container, fn interface{}, opts ...Option) error {
94+
return container.Inject(fn, opts...)
4495
}
4596

4697
// Provide 注册依赖提供者
4798
//
48-
// container: 依赖注入容器
49-
// provider: 提供者函数
99+
// 支持的提供者函数签名:
100+
// - func() T - 简单提供者
101+
// - func() (T, error) - 带错误处理的提供者
102+
// - func(dep1 D1, dep2 D2) T - 带依赖的提供者
103+
// - func(dep1 D1, dep2 D2) (T, error) - 带依赖和错误处理的提供者
104+
//
105+
// 支持的输出类型:
106+
// - 指针类型:*T
107+
// - 接口类型:interface{}
108+
// - 结构体类型:struct{}
109+
// - Map类型:map[K]V
110+
// - Slice类型:[]T
111+
// - 函数类型:func(...)
112+
//
113+
// 不支持的类型:
114+
// - 基本类型:string, int, bool 等(请使用指针类型替代)
115+
//
116+
// 错误处理:
117+
// - 当提供者函数返回 (T, error) 时,如果 error 不为 nil,提供者调用失败
118+
// - 错误会被包装并包含提供者类型和位置信息
119+
// - 提供者注册失败时会 panic(使用 assert.Must)
120+
//
121+
// 示例:
122+
//
123+
// // 简单提供者
124+
// dix.Provide(container, func() *Database {
125+
// return &Database{Host: "localhost"}
126+
// })
127+
//
128+
// // 带错误处理的提供者
129+
// dix.Provide(container, func() (*Config, error) {
130+
// config, err := loadConfig()
131+
// if err != nil {
132+
// return nil, fmt.Errorf("failed to load config: %w", err)
133+
// }
134+
// return config, nil
135+
// })
136+
//
137+
// // 带依赖的提供者
138+
// dix.Provide(container, func(config *Config) (*Database, error) {
139+
// db, err := sql.Open("postgres", config.DatabaseURL)
140+
// if err != nil {
141+
// return nil, fmt.Errorf("failed to connect: %w", err)
142+
// }
143+
// return &Database{DB: db}, nil
144+
// })
145+
//
146+
// 参数:
147+
// - container: 依赖注入容器
148+
// - provider: 提供者函数
50149
func Provide(container Container, provider any) {
51150
assert.Must(container.Provide(provider))
52151
}
53152

54153
// Get 获取指定类型的实例(泛型版本)
55154
//
56-
// container: 依赖注入容器
57-
// opts: 可选配置
155+
// 支持获取的类型:
156+
// - 单个实例:T(直接指定类型)
157+
// - 切片:[]T(获取所有 T 类型的实例)
158+
// - 映射:map[string]T(获取带名称的 T 类型实例)
159+
//
160+
// 类型解析规则:
161+
// - 接口类型会匹配所有实现该接口的类型
162+
// - 结构体类型精确匹配
163+
// - 指针类型匹配对应的指针实例
164+
//
165+
// 错误情况:
166+
// - 类型未注册:返回 ErrTypeNotFound
167+
// - 循环依赖:返回 ErrCircularDependency
168+
// - 提供者调用失败:返回包装后的错误
169+
//
170+
// 示例:
171+
//
172+
// // 获取单个实例
173+
// logger, err := dix.Get[Logger](container)
174+
// if err != nil {
175+
// log.Fatal(err)
176+
// }
177+
//
178+
// // 获取切片
179+
// handlers, err := dix.Get[[]Handler](container)
180+
// if err != nil {
181+
// log.Fatal(err)
182+
// }
183+
//
184+
// // 获取映射
185+
// databases, err := dix.Get[map[string]Database](container)
186+
// if err != nil {
187+
// log.Fatal(err)
188+
// }
189+
//
190+
// 参数:
191+
// - container: 依赖注入容器
192+
// - opts: 可选配置
193+
//
194+
// 返回值:
195+
// - T: 请求的实例
196+
// - error: 获取失败时的错误信息
58197
func Get[T any](container Container, opts ...Option) (T, error) {
59198
return dixinternal.Get[T](container, opts...)
60199
}
61200

62201
// MustGet 获取指定类型的实例,失败时panic(泛型版本)
63202
//
64-
// container: 依赖注入容器
65-
// opts: 可选配置
203+
// 功能与 Get 相同,但在获取失败时会 panic 而不是返回错误。
204+
// 适用于确信实例一定存在的场景,如应用启动阶段。
205+
//
206+
// 支持获取的类型:
207+
// - 单个实例:T(直接指定类型)
208+
// - 切片:[]T(获取所有 T 类型的实例)
209+
// - 映射:map[string]T(获取带名称的 T 类型实例)
210+
//
211+
// 使用场景:
212+
// - 应用启动阶段,确信依赖已正确注册
213+
// - 测试代码中,简化错误处理
214+
// - 配置阶段,依赖缺失应该立即失败
215+
//
216+
// 示例:
217+
//
218+
// // 获取单个实例(确信存在)
219+
// logger := dix.MustGet[Logger](container)
220+
//
221+
// // 获取切片(可能为空)
222+
// handlers := dix.MustGet[[]Handler](container)
223+
//
224+
// // 在应用启动中使用
225+
// func main() {
226+
// container := setupContainer()
227+
//
228+
// // 这些依赖必须存在,否则应用无法启动
229+
// logger := dix.MustGet[Logger](container)
230+
// db := dix.MustGet[*Database](container)
231+
//
232+
// startServer(logger, db)
233+
// }
234+
//
235+
// 参数:
236+
// - container: 依赖注入容器
237+
// - opts: 可选配置
238+
//
239+
// 返回值:
240+
// - T: 请求的实例
241+
//
242+
// 注意:失败时会 panic,请确保在适当的场景下使用
66243
func MustGet[T any](container Container, opts ...Option) T {
67244
return dixinternal.MustGet[T](container, opts...)
68245
}

0 commit comments

Comments
 (0)