API Reference
Complete reference for all godi types and functions.
Collection
Container for service registrations.
Creating a Collection
collection := godi.NewCollection()
Registering Services
// Register with lifetime
err := collection.AddSingleton(constructor, options...)
err := collection.AddScoped(constructor, options...)
err := collection.AddTransient(constructor, options...)
// Add modules
err := collection.AddModules(module1, module2, ...)
Building Provider
// Build with defaults
provider, err := collection.Build()
// Build with options
options := &godi.ProviderOptions{
BuildTimeout: 30 * time.Second,
}
provider, err := collection.BuildWithOptions(options)
Query Methods
// Check if service exists
exists := collection.Contains(reflect.TypeOf((*T)(nil)).Elem())
exists := collection.ContainsKeyed(type, key)
// Get count
count := collection.Count()
// Get all descriptors
descriptors := collection.ToSlice()
// Remove services
collection.Remove(reflect.TypeOf((*T)(nil)).Elem())
collection.RemoveKeyed(type, key)
Provider
Main dependency injection container.
Resolution Methods (Generic)
// Resolve by type
service, err := godi.Resolve[T](provider)
service, err := godi.Resolve[T](scope)
// Resolve by key
service, err := godi.ResolveKeyed[T](provider, "key")
// Resolve group
services, err := godi.ResolveGroup[T](provider, "group")
// Must variants (panic on error)
service := godi.MustResolve[T](provider)
service := godi.MustResolveKeyed[T](provider, "key")
services := godi.MustResolveGroup[T](provider, "group")
Resolution Methods (Reflection)
// Not recommended - use generic methods above
service, err := provider.Get(reflect.TypeOf((*T)(nil)).Elem())
service, err := provider.GetKeyed(type, key)
services, err := provider.GetGroup(type, "group")
Scope Management
// Create scope
scope, err := provider.CreateScope(context.Background())
// Provider info
id := provider.ID()
// Cleanup
err := provider.Close()
Scope
Isolated service lifetime boundary.
// Scope implements Provider interface
service, err := godi.Resolve[T](scope)
// Get context and provider
ctx := scope.Context()
provider := scope.Provider()
// Create nested scope
nestedScope, err := scope.CreateScope(ctx)
// Cleanup
err := scope.Close()
// Get scope from context
scope, ok := godi.FromContext(ctx)
Modules
Organize related services.
Creating Modules
var MyModule = godi.NewModule("name",
godi.AddSingleton(constructor),
godi.AddScoped(constructor),
godi.AddTransient(constructor),
OtherModule, // Include other modules
)
Module Builders
// These return ModuleOption for use in NewModule
godi.AddSingleton(constructor, opts...)
godi.AddScoped(constructor, opts...)
godi.AddTransient(constructor, opts...)
Registration Options
Name Option
Register named/keyed services:
godi.AddSingleton(NewService, godi.Name("primary"))
// Resolve with key
service, _ := godi.ResolveKeyed[Service](provider, "primary")
Group Option
Add services to groups:
godi.AddSingleton(NewValidator, godi.Group("validators"))
// Resolve group
validators, _ := godi.ResolveGroup[Validator](provider, "validators")
As Option
Register as interface:
godi.AddSingleton(NewRedisCache, godi.As(new(Cache)))
// Resolve as interface
cache, _ := godi.Resolve[Cache](provider)
Combining Options
godi.AddSingleton(NewService,
godi.Name("primary"),
godi.As(new(IService)),
)
Parameter Objects
Input Parameters (In)
type ServiceParams struct {
godi.In
// Required dependency
DB Database
// Optional dependency
Cache Cache `optional:"true"`
// Named dependency
Primary Database `name:"primary"`
// Group dependency
Validators []Validator `group:"validators"`
}
func NewService(params ServiceParams) *Service {
// Use params.DB, params.Cache, etc.
}
Output Parameters (Out)
type ServiceBundle struct {
godi.Out
// Register as UserService
UserService UserService
// Register with name
OrderService OrderService `name:"orders"`
// Add to group
AuthHandler http.Handler `group:"handlers"`
}
func NewServices(db Database) ServiceBundle {
return ServiceBundle{
UserService: &userService{db},
OrderService: &orderService{db},
AuthHandler: &authHandler{},
}
}
Disposal Interface
// Implement for automatic cleanup
type Disposable interface {
Close() error
}
// Called automatically when scope/provider closes
Provider Options
type ProviderOptions struct {
// Timeout for building provider
BuildTimeout time.Duration
}
options := &godi.ProviderOptions{
BuildTimeout: 30 * time.Second,
}
provider, err := collection.BuildWithOptions(options)
Lifetimes
const (
Singleton Lifetime = iota // One instance forever
Scoped // One instance per scope
Transient // New instance every time
)
Error Types
// Resolution error
type ResolutionError struct {
ServiceType reflect.Type
ServiceKey any
Cause error
}
// Circular dependency
type CircularDependencyError struct {
Node graph.NodeKey
}
// Lifetime conflict
type LifetimeConflictError struct {
ServiceType reflect.Type
Current Lifetime
Requested Lifetime
}
// Validation error
type ValidationError struct {
ServiceType reflect.Type
Cause error
}
// Build error
type BuildError struct {
Phase string
Details string
Cause error
}
// Disposal error
type DisposalError struct {
Context string
Errors []error
}
Sentinel Errors
var (
ErrServiceNotFound // Service not registered
ErrServiceTypeNil // nil type passed
ErrServiceKeyNil // nil key passed
ErrProviderDisposed // Provider closed
ErrScopeDisposed // Scope closed
ErrConstructorNil // nil constructor
ErrConstructorNoReturn // No return values
ErrConstructorReturnedNil // Returned nil
ErrGroupNameEmpty // Empty group name
ErrSingletonNotInitialized // Singleton not created
)
Complete Example
package main
import (
"context"
"github.com/junioryono/godi/v4"
)
// Services
type Logger struct{}
func NewLogger() *Logger { return &Logger{} }
type Database struct{ logger *Logger }
func NewDatabase(logger *Logger) *Database {
return &Database{logger: logger}
}
type UserService struct{ db *Database }
func NewUserService(db *Database) *UserService {
return &UserService{db: db}
}
func main() {
// Create module
appModule := godi.NewModule("app",
godi.AddSingleton(NewLogger),
godi.AddSingleton(NewDatabase),
godi.AddScoped(NewUserService),
)
// Build provider
collection := godi.NewCollection()
collection.AddModules(appModule)
provider, err := collection.Build()
if err != nil {
panic(err)
}
defer provider.Close()
// Create scope
scope, err := provider.CreateScope(context.Background())
if err != nil {
panic(err)
}
defer scope.Close()
// Resolve service
service, err := godi.Resolve[*UserService](scope)
if err != nil {
panic(err)
}
// Use service
service.DoWork()
}