Your First Container
A container holds your application’s services. You register services with a collection, then build it into a provider that creates instances on demand.
The Pattern
Collection (registration) → Build → Provider (resolution)
Step 1: Create a Collection
services := godi.NewCollection()
The collection is where you tell godi about your services.
Step 2: Register a Service
services.AddSingleton(func() string {
return "Hello, godi!"
})
This registers a string service. Singleton constructors run once, during Build(); scoped and transient constructors run when the service is needed.
Step 3: Build the Provider
provider, err := services.Build()
if err != nil {
log.Fatal(err)
}
defer provider.Close()
Building validates your registrations and prepares the dependency graph. Always close the provider when done - it cleans up resources.
Step 4: Resolve the Service
message := godi.MustResolve[string](provider)
fmt.Println(message) // Hello, godi!
MustResolve returns the service or panics. Use Resolve if you want to handle errors yourself.
Complete Example
package main
import (
"fmt"
"log"
"github.com/junioryono/godi/v5"
)
func main() {
// 1. Create collection
services := godi.NewCollection()
// 2. Register service
services.AddSingleton(func() string {
return "Hello, godi!"
})
// 3. Build provider
provider, err := services.Build()
if err != nil {
log.Fatal(err)
}
defer provider.Close()
// 4. Use service
message := godi.MustResolve[string](provider)
fmt.Println(message)
}
What Just Happened?
┌─────────────────────────────────────────────────────┐
│ Collection │
│ ┌─────────────────────────────────────────────┐ │
│ │ string → func() string { return "Hello" } │ │
│ └─────────────────────────────────────────────┘ │
└────────────────────────┬────────────────────────────┘
│ Build()
▼
┌─────────────────────────────────────────────────────┐
│ Provider │
│ ┌─────────────────────────────────────────────┐ │
│ │ MustResolve[string]() → "Hello, godi!" │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
You registered a
stringservice with a factory functionBuilding validated the dependency graph and called your factory (singletons are created eagerly)
Resolving returned the cached instance
Key Points
Collection is for registration (before the app runs)
Provider is for resolution (while the app runs)
Build validates everything upfront - no runtime surprises
Close cleans up resources when you’re done