Install
/plugin marketplace add go-kid/iocRun inside Claude Code, then install plugins from it. Check the repo's README before you run it.
Plugins 1
After adding the marketplace, install one with /plugin install <name>@go-kid-ioc.
- 1iocgo-kid/ioc dependency injection framework with comprehensive skills for development (ioc-dev), debugging (ioc-debug), and testing/extension (ioc-test)
/plugin install ioc@go-kid-ioc
Files
go-kid/ioc
English | 中文
go-kid/ioc is a Go runtime dependency injection (IoC/DI) framework based on tag + interface.
✨ Features
- Component Dependency Injection (
wiretag)- Inject by pointer type, interface type, or component name
- Multiple implementation selection strategies (Primary/Qualifier)
- Inject into interface slices/arrays
- Configuration Injection (
value/prop/prefixtags)- Multiple configuration sources (command-line args, files, raw content)
- Configuration placeholders
${...} - Expression evaluation
#{...}(arithmetic, logical, conditional, collection operations)
- Lifecycle Management: ApplicationRunner, CloserComponent, LazyInitComponent
context.Contextlifecycle support: WithContext variants for all lifecycle interfaces- Scope mechanism: Singleton/Prototype
- Conditional component registration: Register components based on runtime conditions
- Application event mechanism: Publish and listen for application events
log/slogadapter support: Integrate with Go's structured logging
📦 Installation
Requires Go 1.21+.
go get github.com/go-kid/ioc
🚀 Quick Start
package main
import (
"fmt"
"github.com/go-kid/ioc"
)
// Component to be injected
type ComponentA struct {
Name string
}
func (a *ComponentA) GetName() string {
return a.Name
}
// Target struct that depends on ComponentA
type App struct {
ComponentA *ComponentA `wire:""` // pointer + exported field + wire tag
}
func main() {
a := new(App)
// Register components
ioc.Register(a)
ioc.Register(&ComponentA{Name: "Comp-A"})
// Run the framework
_, err := ioc.Run()
if err != nil {
panic(err)
}
// Output: "Comp-A"
fmt.Println(a.ComponentA.GetName())
}
Key points: Dependency fields must be exported (start with uppercase) and use
wire:""to declare injection.
📖 Documentation
1. Component Dependency Injection (wire tag)
Component injection is controlled via tag: wire:"<name>,arg1=xxx,arg2=yyy"
<name>: optional, inject by component name,arg=...: optional extra arguments (e.g.,qualifier)wire:""(empty) means inject by type
Inject by Pointer Type
type Component struct {
Name string
}
type App struct {
C *Component `wire:""` // injected by *Component type
}
Inject by Interface Type
type IComponent interface {
GetName() string
}
type ComponentA struct{ Name string }
func (a *ComponentA) GetName() string { return a.Name }
type App struct {
C IComponent `wire:""` // inject by interface type
}
Inject by Name
Implement NamingComponent interface to define component names:
type ComponentA struct {
Name string
componentName string
}
func (a *ComponentA) Naming() string { return a.componentName }
type App struct {
ByName IComponent `wire:"comp-A"` // inject by component name
}
Multiple Implementation Selection Strategy
When an interface has multiple implementations, the container selects by priority:
- Components implementing
WirePrimaryinterface (primary) - Components without alias (not implementing
Naming()) - One will be chosen (order not guaranteed)
Using Primary marker:
type ComponentA struct {
Name string
definition.WirePrimaryComponent // embed Primary component
}
Using Qualifier:
type ComponentA struct {
qualifier string
}
func (a *ComponentA) Qualifier() string { return a.qualifier }
type App struct {
C IComponent `wire:",qualifier=comp-A"` // use qualifier
}
Inject into Slice/Array
type App struct {
All []Interface `wire:""` // all Interface implementations
}
2. Configuration Injection
prefix: Bind Config Prefix
type configA struct {
B int `yaml:"b"`
C []int `yaml:"c"`
}
type App struct {
A *configA `prefix:"a"` // bind config prefix "a"
}
Configuration (YAML):
a: b: 123 c: [1,2,3,4]
value: Literals / Placeholders / Expressions
type T struct {
DSN string `value:"${db.dsn}"` // config placeholder
Sum int `value:"#{1+2}"` // expression
Str string `value:"foo"` // literal
}
prop: Sugar for value
type DBConfig struct {
DSN string `prop:"db.dsn"` // equivalent to value:"${db.dsn}"
}
Placeholders and Expressions
${...}: Configuration placeholder, reads value from config#{...}: Expression evaluation, supports arithmetic, logical, conditional, collection operations
Example:
type T struct {
Arithmetic int `value:"#{1+(1*2)}"` // 3
Comparison bool `value:"#{1/1==1}"` // true
Conditional string `value:"#{1>2?'a':'b'}"` // "b"
WithConfig int `value:"#{${number.val1}+${number.val2}}"` // use config
}
3. Application Startup
Style 1: Use ioc.Run / ioc.Register
ioc.Register(a)
ioc.Register(&ComponentA{Name: "Comp-A"})
_, err := ioc.Run()
Style 2: Work with app.App Directly
application := app.NewApp()
err := application.Run(
app.SetComponents(...),
app.SetConfigLoader(loader.NewFileLoader("config.yaml")),
app.SetConfigBinder(binder.NewViperBinder("yaml")),
)
4. Lifecycle Interfaces
ApplicationRunner: executed after all components are refreshedCloserComponent:Close()called when app stopsLazyInitComponent: marked as lazy initializationPriorityComponent: controls post-processor execution orderInitializeComponentWithContext/InitializingComponentWithContext: context-aware Init/AfterPropertiesSetApplicationRunnerWithContext: context-aware RunCloserComponentWithContext: context-aware CloseDestructionAwareComponentPostProcessor: callback before created singletons are destroyedScopeComponent: control component scope (singleton/prototype)ConditionalComponent: conditional registration based on runtime conditionsApplicationEventListener/ApplicationEventPublisher: event mechanism
5. Context Support
All lifecycle interfaces have WithContext variants. Components can implement them to receive a context.Context for timeout control, cancellation propagation, etc.
// Run the framework with a context app, err := ioc.RunWithContext(ctx) // Set a shutdown timeout _, err := ioc.Run(app.SetShutdownTimeout(30 * time.Second))
Context-aware lifecycle interfaces:
// InitializeComponentWithContext (replaces InitializeComponent)
func (c *MyComp) Init(ctx context.Context) error { return nil }
// InitializingComponentWithContext (replaces InitializingComponent)
func (c *MyComp) AfterPropertiesSet(ctx context.Context) error { return nil }
// ApplicationRunnerWithContext (can coexist with ApplicationRunner)
func (r *MyRunner) RunWithContext(ctx context.Context) error { return nil }
// CloserComponentWithContext (can coexist with CloserComponent)
func (c *MyComp) CloseWithContext(ctx context.Context) error { return nil }
Note:
Init(ctx)andAfterPropertiesSet(ctx)have the same method names as their base interfaces but different signatures, so a component implements one or the other.RunWithContextandCloseWithContextuse distinct method names, allowing a component to implement both the original and context-aware versions.
6. Scope
Control component scope by implementing ScopeComponent:
- Singleton (default): single instance in the container
- Prototype: a new instance is shallow-copied from the registered template and fully populated on every access; it is not eagerly created
import "github.com/go-kid/ioc/definition"
type MyPrototype struct{}
func (p *MyPrototype) Scope() string { return definition.ScopePrototype }
7. Conditional Registration
Implement ConditionalComponent to decide at runtime whether a component should be created:
import "github.com/go-kid/ioc/definition"
type MyComp struct{}
func (c *MyComp) Condition(ctx definition.ConditionContext) bool {
return ctx.HasComponent("dependency")
}
8. Events
Publish and listen for application events to enable loose coupling between components:
import "github.com/go-kid/ioc/definition"
// Listen for events
type MyListener struct{}
func (l *MyListener) OnEvent(event definition.ApplicationEvent) error {
// handle event
return nil
}
Built-in events: ComponentCreatedEvent after a component is initialized, ApplicationStartedEvent after runners complete, and ApplicationClosingEvent before shutdown. On shutdown, destruction-aware post-processors run for created singletons in reverse creation order, then closer components run concurrently. Prototype instances are owned by their callers and are not destroyed automatically.
🏗️ Architecture
┌─────────────────────────────────────────────────────────────────┐
│ app.App │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Component Factory│ │ Configure │ │
│ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │
│ │ │ │
│ ┌────────▼─────────┐ ┌────────▼─────────┐ │
│ │ DefinitionRegistry│ │ Loader │ │
│ │ SingletonRegistry│ │ (args/file/raw) │ │
│ └────────┬─────────┘ └────────┬─────────┘ │
│ │ │ │
│ │ register │ │
│ ┌────────▼─────────┐ ┌────────▼─────────┐ │
│ │ComponentDefinition│ │ Binder │ │
│ └────────┬─────────┘ │ (viper) │ │
│ │ └───────────────────┘ │
│ │ create │
│ ┌────────▼─────────┐ │
│ │ Instance │ │
│ └────────┬─────────┘ │
│ │ │
│ ┌────────▼──────────────────────────────────────────┐ │
│ │ PostProcessors │ │
│ │ ┌────────────────────────────────────────────┐ │ │
│ │ │ • LoggerAware │ │ │
│ │ │ • ConfigQuoteAware ${...} │ │ │
│ │ │ • ExpressionTagAware #{...} │ │ │
│ │ │ • PropertiesAware prefix │ │ │
│ │ │ • ValueAware value/prop │ │ │
│ │ │ • DependencyAware wire │ │ │
│ │ │ • DependencyFunctionAware func │ │ │
│ │ └────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Config Flow: Binder → ConfigQuoteAware, PropertiesAware, ValueAware, ExpressionTagAware
📚 Examples & Tests
- Example projects:
examples/debug_demo,examples/post_processor - Post processor example:
examples/post_processor/ - Performance tools:
cmd/performance_analyst/ - Unit tests:
unittest/component/builtin_inject/*,unittest/configure/*
Run tests:
go test ./...
Pull requests and pushes to main also run the race detector, go vet, go build, and enforce at least 75% repository-wide statement coverage in GitHub Actions.
📄 License
🤝 Contributing
Contributions via Issues / PRs are welcome. Please ensure go test ./... passes before submitting.
{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "go-kid-ioc",
"description": "go-kid/ioc dependency injection framework with development, debugging, and testing skills",
"owner": {
"name": "go-kid",
"url": "https://github.com/go-kid/ioc"
},
"plugins": [
{
"name": "ioc",
"description": "go-kid/ioc dependency injection framework with comprehensive skills for development (ioc-dev), debugging (ioc-debug), and testing/extension (ioc-test)",
"version": "1.0.0",
"author": {
"name": "go-kid",
"url": "https://github.com/go-kid"
},
"source": "./",
"category": "library-reference",
"homepage": "https://github.com/go-kid/ioc",
"tags": [
"dependency-injection",
"ioc",
"go",
"golang",
"framework",
"di"
]
}
]
}Facts
- Kind
- Marketplace
- Repo
- go-kid/ioc
- Group
- Uncategorized
- Stars
- 1
- Marketplace name
- go-kid-ioc
- Owner
- go-kid
- License
- Apache-2.0
- Language
- Go
- Created
- 2023-04-04
- Last push
- 2026-09-09
- Plugins
- 1
- 1obra/superpowersobra/superpowersAn agentic skills framework & software development methodology that works.297.9k
- 2affaan-m/everything-claude-codeaffaan-m/ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.277.5k
- 3anthropics/skillsanthropics/skillsPublic repository for Agent Skills180.6k
- 4f/prompts.chatf/prompts.chatf.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete privacy.172.7k
- 5anthropics/claude-codeanthropics/claude-codeClaude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.150.3k
- 6nextlevelbuilder/ui-ux-pro-max-skillnextlevelbuilder/ui-ux-pro-max-skillAn AI skill that provides design intelligence for building professional UI/UX across multiple platforms.135k