From ioc-dev
go-kid/ioc framework development guide covering component dependency injection, configuration binding, and application lifecycle. ALWAYS use this skill when the user asks about: dependency injection, wiring components, component registration, wire tag, constructor injection, config injection, value/prop/prefix tags, placeholders ${...}, expressions #{...}, application startup, ioc.Run, app.NewApp, lifecycle methods (Init/AfterPropertiesSet/Run/Close), ApplicationRunner, graceful shutdown, or ANY go-kid/ioc development questions. Also use for questions like 'how do I inject X', 'how to load config', 'how to start my app', 'what's the startup sequence', 'how to choose between implementations', 'config value not working', or any component wiring, configuration binding, and lifecycle management. Triggers on: dependency injection, DI, IoC, wire tag, component registration, ioc.Register, ioc.Provide, app.SetComponents, constructor injection, value tag, prop tag, prefix tag, config, ${...}, #{...}, ConfigurationProperties, ioc.Run, ioc.RunWithContext, app.NewApp, ApplicationRunner, lifecycle, Init, AfterPropertiesSet, Close, startup, shutdown, Qualifier, Primary, NamingComponent, ScopeComponent, ConditionalComponent, LazyInit, Ordered, events.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ioc-dev:ioc-devThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Comprehensive guide for developing applications with the **go-kid/ioc** dependency injection framework.
Comprehensive guide for developing applications with the go-kid/ioc dependency injection framework.
Requires Go 1.21+
在使用 go-kid/ioc 时,必须遵守以下规则,违反会导致注入失败或运行时错误:
// ❌ 错误 - 小写字段会被忽略
type Service struct {
repo *Repository `wire:""` // 不会被注入!
}
// ✅ 正确 - 首字母大写
type Service struct {
Repo *Repository `wire:""` // 会被正确注入
}
❌ 禁止直接访问 configure 对象:
// ❌ 错误 - 不要直接注入或访问 configure
type Service struct {
Configure configure.Configure `wire:""` // 错误!
}
func (s *Service) Init() {
// ❌ 错误 - 不要直接调用 configure.Get()
host := s.Configure.Get("db.host")
}
✅ 必须使用以下方式之一:
// 方式 1: 使用 prop/value/prefix tag
type Service struct {
Host string `prop:"db.host"` // ✅ 单个配置值
Port int `value:"${db.port:3306}"` // ✅ 带默认值
DB *DBConfig `prefix:"database"` // ✅ 绑定配置树
}
// 方式 2: 实现 ConfigurationProperties 接口
type DBConfig struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
}
func (c *DBConfig) Prefix() string { return "database" }
// 方式 3: 构造函数参数(自动绑定)
func NewService(cfg *DBConfig) *Service { // cfg 会自动从配置加载
return &Service{host: cfg.Host}
}
// ❌ 错误
ioc.Register(MyService{})
// ✅ 正确
ioc.Register(&MyService{})
import "github.com/go-kid/ioc"
// Register components
ioc.Register(&MyService{}, &Repository{})
// Start application
app, err := ioc.Run()
if err != nil {
panic(err)
}
defer app.Close()
type MyService struct {
Repo *Repository `wire:""` // inject by type
Logger Logger `wire:""` // inject interface
Config *AppConfig `prefix:"app"` // bind config
Port int `prop:"server.port:8080"` // config value with default
}
func NewService(repo *Repository, cfg *DBConfig) *Service {
return &Service{repo: repo, cfg: cfg}
}
ioc.Register(NewService, &Repository{})
ioc.Run(app.SetConfig("config.yaml"))
This skill covers three core areas. For detailed information, consult the reference documents:
When to use: Registering components, dependency wiring, selecting implementations
Quick reference:
ioc.Register(&MyComp{}) or ioc.Provide[T](constructor)Svc *Service \wire:""``Svc *Service \wire:"my-service"``Svcs []Service \wire:""``Comp *MyComp \func:"MethodName"``definition.WirePrimaryComponentwire:",qualifier=groupA"wire:",required=false"ScopeComponent → ScopeSingleton / ScopePrototype📖 Full documentation: references/component-injection.md
When to use: Loading config files, binding config values, placeholders, expressions
Quick reference:
app.SetConfig("config.yaml")DB *DBConfig \prefix:"database"``Host string \prop:"server.host"``DSN string \value:"${db.dsn}"``Port int \value:"${port:8080}"``Sum int \value:"#{1+2}"``Total int \value:"#{${price} * ${qty}}"``Prefix() string📖 Full documentation: references/config-injection.md
When to use: App startup, initialization order, lifecycle hooks, shutdown, events
Quick reference:
ioc.Run(options...)ioc.RunWithContext(ctx, options...)AfterPropertiesSet() errorInit() errorApplicationRunner → Run() errorClose() errorOrder() intdefinition.LazyInitComponentCondition(ctx ConditionContext) boolApplicationEventListener📖 Full documentation: references/lifecycle.md
type UserService struct {
Repo *UserRepository `wire:""`
Cache *Redis `wire:""`
Config *ServiceConfig `prefix:"user-service"`
}
func (s *UserService) Init() error {
// Initialize after dependencies injected
return s.Cache.Connect(s.Config.RedisURL)
}
func NewUserService(repo *UserRepository, cfg *ServiceConfig) *UserService {
return &UserService{repo: repo, config: cfg}
}
// Type-safe: panics if return type doesn't match
ioc.Provide[UserService](NewUserService)
// Mark implementations
type MySQLRepo struct{}
func (r *MySQLRepo) Qualifier() string { return "mysql" }
type PostgresRepo struct{}
func (r *PostgresRepo) Qualifier() string { return "postgres" }
// Select by qualifier
type App struct {
MySQL Repository `wire:",qualifier=mysql"`
Postgres Repository `wire:",qualifier=postgres"`
AllRepos []Repository `wire:""` // gets both
}
type HTTPServer struct {
Port int `prop:"server.port:8080"`
server *http.Server
}
func (s *HTTPServer) Run() error {
s.server = &http.Server{Addr: fmt.Sprintf(":%d", s.Port)}
return s.server.ListenAndServe()
}
func (s *HTTPServer) Close() error {
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
return s.server.Shutdown(ctx)
}
ioc.Run(options...)
1. Apply SettingOptions + global settings
2. Load configuration (loaders → binder)
3. Scan component definitions
4. Resolve dependencies & create components
5. Inject dependencies (wire, value, prop, prefix tags)
6. Call lifecycle hooks (AfterPropertiesSet → Init)
7. Execute ApplicationRunners (in Order)
8. Publish ApplicationStartedEvent
参见文档开头的 ⚠️ 核心约束 了解必须遵守的规则
ioc.Register(&MyService{}) not MyService{}wire:"" tags on unexported fields are ignoredconfigure.Configure directly; use value/prop/prefix tags or ConfigurationPropertiesrequired=false to make injection optionalprop vs value: prop:"key" equals value:"${key}"When you need detailed information on a specific topic, read the corresponding reference file. The main topics are:
For debugging and troubleshooting, use the ioc-debug skill. For testing and extensions, use the ioc-test skill.
npx claudepluginhub go-kid/ioc --plugin iocGuides dependency injection in Go: manual constructor injection, DI library comparison (google/wire, uber-go/dig, uber-go/fx, samber/do). Use when designing service architecture or refactoring tightly coupled code.
Covers .NET dependency injection patterns: service lifetimes, keyed services, decorator pattern, and common pitfalls. Useful when registering services or resolving lifetime issues.
Provides idiomatic Go patterns for backend APIs with Gin, Echo, Fiber: standard project structure, custom error handling, handler dependency injection, concurrency best practices.