Documentation
ΒΆ
Index ΒΆ
- Variables
- func IsCircularDependency(err error) bool
- func IsDisposed(err error) bool
- func IsNotFound(err error) bool
- func IsTimeout(err error) bool
- func Resolve[T any](s Scope) (T, error)
- func ResolveGroup[T any](s Scope, groupName string) ([]T, error)
- func ResolveKeyed[T any](s Scope, serviceKey any) (T, error)
- func SetDefaultServiceProvider(provider ServiceProvider)
- type AlreadyRegisteredError
- type BeforeCallback
- type BeforeCallbackInfo
- type Callback
- type CallbackInfo
- type CircularDependencyError
- type DecorateInfo
- type DecorateOption
- type Disposable
- type DisposableWithContext
- type In
- type Input
- type InvokeInfo
- type InvokeOption
- type LifetimeConflictError
- type LifetimeError
- type MissingConstructorError
- type ModuleError
- type ModuleOption
- type Out
- type Output
- type ProvideInfo
- type ProvideOption
- type RegistrationError
- type ResolutionError
- type Scope
- type ScopeOption
- type ServiceLifetime
- func (sl ServiceLifetime) IsValid() bool
- func (sl ServiceLifetime) MarshalJSON() ([]byte, error)
- func (sl ServiceLifetime) MarshalText() ([]byte, error)
- func (sl ServiceLifetime) String() string
- func (sl *ServiceLifetime) UnmarshalJSON(data []byte) error
- func (sl *ServiceLifetime) UnmarshalText(text []byte) error
- type ServiceProvider
- type ServiceProviderOptions
- type TimeoutError
- type TypeMismatchError
- type ValidationError
Constants ΒΆ
This section is empty.
Variables ΒΆ
var ( // Service resolution errors. ErrServiceNotFound = errors.New("service not found") ErrServiceKeyNil = errors.New("service key cannot be nil") ErrInvalidServiceType = errors.New("invalid service type") ErrFailedToExtractService = errors.New("failed to extract service") ErrFailedToExtractKeyedService = errors.New("failed to extract keyed service") // Lifecycle errors. ErrDisposed = errors.New("disposed") ErrNilScope = errors.New("scope cannot be nil") ErrScopeDisposed = errors.New("scope has been disposed") ErrProviderDisposed = errors.New("service provider has been disposed") // Constructor/registration errors. ErrNilConstructor = errors.New("constructor cannot be nil") ErrNilServiceProvider = errors.New("service provider cannot be nil") ErrConstructorNotFunction = errors.New("constructor must be a function") ErrConstructorNoReturn = errors.New("constructor must return at least one value") ErrConstructorTooManyReturns = errors.New("constructor must return at most 2 values") ErrConstructorInvalidSecondReturn = errors.New("constructor's second return value must be error") ErrConstructorMultipleIn = errors.New("constructor cannot have multiple In parameters") ErrConstructorOutMaxReturns = errors.New("constructor with Out must return at most 2 values") // Decorator errors. ErrDecoratorNil = errors.New("decorator cannot be nil") ErrDecoratorNotFunction = errors.New("decorator must be a function") ErrDecoratorNoParams = errors.New("decorator must have at least one parameter") ErrDecoratorNoReturn = errors.New("decorator must return at least one value") // Collection/descriptor errors. ErrCollectionBuilt = errors.New("service collection has already been built") ErrCollectionModifyAfterBuild = errors.New("cannot modify service collection after build") ErrDescriptorNil = errors.New("descriptor cannot be nil") ErrNoConstructorOrDecorator = errors.New("constructor or decorator must be provided") ErrBothConstructorAndDecorator = errors.New("cannot have both constructor and decorator") // Provider errors. ErrServicesNil = errors.New("services cannot be nil") ErrProviderFunctionNotFound = errors.New("provider function not found") ErrKeyedProviderFunctionNotFound = errors.New("keyed provider function not found") ErrConstructorMustReturnValue = errors.New("constructor must be a function that returns at least one value") ErrServiceHasNoConstructor = errors.New("service has no constructor") ErrDescriptorHasNoConstructor = errors.New("descriptor has no constructor") ErrFailedToCreateScope = errors.New("failed to create dig scope: dig container is nil") // Special cases. ErrResultObjectConstructor = errors.New("constructor returns Out - use collection.Add* methods") ErrReplaceResultObject = errors.New("replace not supported for result object constructors") // Context errors ErrScopeNotInContext = errors.New("no scope found in context") )
var As = dig.As
As is an option that specifies that the value produced by the constructor implements one or more other interfaces and should be provided as those interfaces.
Example:
collection.AddSingleton(NewPostgresDB, godi.As(new(Reader), new(Writer)))
This makes the PostgresDB available as both Reader and Writer interfaces.
var FillDecorateInfo = dig.FillDecorateInfo
FillDecorateInfo is an option that writes information about what dig was able to get out of the provided decorator.
var FillInvokeInfo = dig.FillInvokeInfo
FillInvokeInfo is an option that writes information about what dig was able to get out of the invoked function.
Example:
var info godi.InvokeInfo provider.Invoke(myFunc, godi.FillInvokeInfo(&info))
var FillProvideInfo = dig.FillProvideInfo
FillProvideInfo is an option that writes information about what dig was able to get out of the provided constructor.
Example:
var info godi.ProvideInfo collection.AddSingleton(NewService, godi.FillProvideInfo(&info))
var Group = dig.Group
Group is an option for providing values to a group. Groups allow multiple values of the same type to be collected into a slice.
Example:
collection.AddSingleton(NewUserHandler, godi.Group("routes"))
collection.AddSingleton(NewAdminHandler, godi.Group("routes"))
collection.AddSingleton(NewAPIHandler, godi.Group("routes"))
// Then consume all handlers:
type ServerParams struct {
godi.In
Handlers []http.Handler `group:"routes"`
}
var IsIn = dig.IsIn
IsIn checks whether the given struct is a dig.In struct. This is re-exported from dig for convenience.
var IsOut = dig.IsOut
IsOut checks whether the given struct is a dig.Out struct. This is re-exported from dig for convenience.
var Name = dig.Name
Name is an option for providing named values. This can be used with collection.AddSingletonInstance and similar methods.
Example:
collection.AddSingletonInstance(redisCache, godi.Name("redis"))
collection.AddSingletonInstance(memCache, godi.Name("memory"))
var WithDecoratorBeforeCallback = dig.WithDecoratorBeforeCallback
WithDecoratorBeforeCallback returns a DecorateOption for adding a callback that runs before the decorator starts.
var WithDecoratorCallback = dig.WithDecoratorCallback
WithDecoratorCallback returns a DecorateOption for adding a callback that runs after the decorator finishes.
var WithProviderBeforeCallback = dig.WithProviderBeforeCallback
WithProviderBeforeCallback returns a ProvideOption for adding a callback that runs before the constructor starts.
var WithProviderCallback = dig.WithProviderCallback
WithProviderCallback returns a ProvideOption for adding a callback that runs after the constructor finishes.
Example:
collection.AddSingleton(NewService, godi.WithProviderCallback(func(ci godi.CallbackInfo) {
log.Printf("Service created in %v", ci.Runtime)
}))
Functions ΒΆ
func IsCircularDependency ΒΆ
IsCircularDependency checks if an error is due to circular dependencies.
func IsDisposed ΒΆ
IsDisposed checks if an error indicates a disposed scope or provider.
func IsNotFound ΒΆ
IsNotFound checks if an error indicates a service was not found.
func ResolveGroup ΒΆ
ResolveGroup is a generic helper function that returns the group services as type []T.
func ResolveKeyed ΒΆ
ResolveKeyed is a generic helper function that returns the keyed service as type T.
func SetDefaultServiceProvider ΒΆ
func SetDefaultServiceProvider(provider ServiceProvider)
SetDefault sets the default ServiceProvider used by the package-level functions. This is similar to slog.SetDefault.
After this call, package-level functions like Resolve, Invoke, etc. will use this provider. Pass nil to remove the default provider.
Types ΒΆ
type AlreadyRegisteredError ΒΆ
AlreadyRegisteredError indicates a service type is already registered.
func (AlreadyRegisteredError) Error ΒΆ
func (e AlreadyRegisteredError) Error() string
type BeforeCallback ΒΆ
type BeforeCallback = dig.BeforeCallback
BeforeCallback is a function called before a constructor or decorator runs.
type BeforeCallbackInfo ΒΆ
type BeforeCallbackInfo = dig.BeforeCallbackInfo
BeforeCallbackInfo contains information about a constructor call before it runs.
type CallbackInfo ΒΆ
type CallbackInfo = dig.CallbackInfo
CallbackInfo contains information about a constructor call.
type CircularDependencyError ΒΆ
type CircularDependencyError struct {
ServiceType reflect.Type
Chain []reflect.Type // If available from parsing the error
DigError error // The underlying dig error
}
CircularDependencyError represents a circular dependency in the container.
func (CircularDependencyError) Error ΒΆ
func (e CircularDependencyError) Error() string
func (CircularDependencyError) Unwrap ΒΆ
func (e CircularDependencyError) Unwrap() error
type DecorateInfo ΒΆ
type DecorateInfo = dig.DecorateInfo
DecorateInfo contains information about a decorated type.
type DecorateOption ΒΆ
type DecorateOption = dig.DecorateOption
DecorateOption modifies the default behavior of Decorate.
type Disposable ΒΆ
type Disposable interface {
// Close disposes the resource with the provided context.
// Implementations should respect context cancellation for graceful shutdown.
Close() error
}
Disposable allows disposal with context for graceful shutdown. Services implementing this interface can perform context-aware cleanup.
Example:
type DatabaseConnection struct {
conn *sql.DB
}
func (dc *DatabaseConnection) Close() error {
return dc.conn.Close()
}
type DisposableWithContext ΒΆ
type DisposableWithContext interface {
// Close disposes the resource with the provided context.
// Implementations should respect context cancellation for graceful shutdown.
Close(ctx context.Context) error
}
DisposableWithContext allows disposal with context for graceful shutdown. Services implementing this interface can perform context-aware cleanup.
Example:
type DatabaseConnection struct {
conn *sql.DB
}
func (dc *DatabaseConnection) Close(ctx context.Context) error {
done := make(chan error, 1)
go func() {
done <- dc.conn.Close()
}()
select {
case err := <-done:
return err
case <-ctx.Done():
return ctx.Err()
}
}
type In ΒΆ
In embeds dig.In to leverage dig's parameter object functionality. When a constructor function accepts a single struct parameter with embedded In, dig will automatically populate all exported fields of that struct with the corresponding services.
This is a direct wrapper around dig.In, so all dig features are supported:
- `optional:"true"` - Field is optional and won't cause an error if the service is not found
- `name:"serviceName"` - Field should be resolved as a keyed/named service
- `group:"groupName"` - Field should be filled from a value group (slice fields only)
Example:
type ServiceParams struct {
godi.In
Database *sql.DB
Logger Logger `optional:"true"`
Cache Cache `name:"redis"`
Handlers []http.Handler `group:"routes"`
}
func NewService(params ServiceParams) *Service {
return &Service{
db: params.Database,
logger: params.Logger, // might be nil if not registered
cache: params.Cache,
handlers: params.Handlers,
}
}
The In struct must be embedded anonymously:
type ServiceParams struct {
godi.In // β Correct - anonymous embedding
// ...
}
type ServiceParams struct {
In godi.In // β Wrong - named field
// ...
}
type InvokeInfo ΒΆ
type InvokeInfo = dig.InvokeInfo
InvokeInfo contains information about an invoked function.
type InvokeOption ΒΆ
type InvokeOption = dig.InvokeOption
InvokeOption modifies the default behavior of Invoke.
type LifetimeConflictError ΒΆ
type LifetimeConflictError struct {
ServiceType reflect.Type
Current ServiceLifetime
Requested ServiceLifetime
}
LifetimeConflictError indicates a service is registered with conflicting lifetimes.
func (LifetimeConflictError) Error ΒΆ
func (e LifetimeConflictError) Error() string
type LifetimeError ΒΆ
type LifetimeError struct {
Value any
}
LifetimeError indicates an invalid service lifetime value.
func (LifetimeError) Error ΒΆ
func (e LifetimeError) Error() string
type MissingConstructorError ΒΆ
type MissingConstructorError struct {
ServiceType reflect.Type
Context string // "service" or "descriptor"
}
MissingConstructorError indicates a service has no constructor.
func (MissingConstructorError) Error ΒΆ
func (e MissingConstructorError) Error() string
type ModuleError ΒΆ
ModuleError wraps errors from module registration.
func (ModuleError) Error ΒΆ
func (e ModuleError) Error() string
func (ModuleError) Unwrap ΒΆ
func (e ModuleError) Unwrap() error
type ModuleOption ΒΆ
type ModuleOption func(ServiceProvider) error
ModuleOption represents a registration action within a module.
func AddDecorator ΒΆ
func AddDecorator(decorator any, opts ...DecorateOption) ModuleOption
AddDecorator creates a ModuleBuilder for adding a decorator.
func AddScoped ΒΆ
func AddScoped(constructor any, opts ...ProvideOption) ModuleOption
AddScoped creates a ModuleBuilder for adding a scoped service.
func AddSingleton ΒΆ
func AddSingleton(constructor any, opts ...ProvideOption) ModuleOption
AddSingleton creates a ModuleBuilder for adding a singleton service.
func NewModule ΒΆ
func NewModule(name string, builders ...ModuleOption) ModuleOption
NewModule creates a new module with the given name and builders. Modules are a way to group related service registrations together.
Example:
var DatabaseModule = godi.NewModule("database",
godi.AddSingleton(NewDatabaseConnection),
godi.AddScoped(NewUserRepository),
godi.AddScoped(NewOrderRepository),
)
var CacheModule = godi.NewModule("cache",
godi.AddSingleton(cache.New[any]),
godi.AddSingleton(NewCacheMetrics),
)
var AppModule = godi.NewModule("app",
DatabaseModule,
CacheModule,
godi.AddScoped(NewAppService),
)
type Out ΒΆ
Out embeds dig.Out to leverage dig's result object functionality. When a constructor returns a struct with embedded Out, each exported field of that struct is registered as a separate service in the container.
This is a direct wrapper around dig.Out, so all dig features are supported:
- `name:"serviceName"` - Field should be registered as a keyed/named service
- `group:"groupName"` - Field should be added to a value group
Example:
type ServiceResult struct {
godi.Out
UserService *UserService
AdminService *AdminService `name:"admin"`
Handler http.Handler `group:"routes"`
}
func NewServices(db *sql.DB) ServiceResult {
userSvc := newUserService(db)
adminSvc := newAdminService(db)
return ServiceResult{
UserService: userSvc,
AdminService: adminSvc,
Handler: newAPIHandler(userSvc),
}
}
Multiple handlers example with groups:
type Handlers struct {
godi.Out
UserHandler http.Handler `group:"routes"`
AdminHandler http.Handler `group:"routes"`
APIHandler http.Handler `group:"routes"`
}
The Out struct must be embedded anonymously:
type ServiceResult struct {
godi.Out // β Correct - anonymous embedding
// ...
}
type ServiceResult struct {
Out godi.Out // β Wrong - named field
// ...
}
Result objects are automatically handled by the regular Add* methods:
collection.AddSingleton(NewServices) // Each field in ServiceResult is registered
type ProvideInfo ΒΆ
type ProvideInfo = dig.ProvideInfo
ProvideInfo contains information about a provided constructor.
type ProvideOption ΒΆ
type ProvideOption = dig.ProvideOption
ProvideOption modifies the default behavior of Provide.
type RegistrationError ΒΆ
type RegistrationError struct {
ServiceType reflect.Type
Operation string // "provide", "decorate", etc.
Cause error
}
RegistrationError wraps errors during service registration.
func (RegistrationError) Error ΒΆ
func (e RegistrationError) Error() string
func (RegistrationError) Unwrap ΒΆ
func (e RegistrationError) Unwrap() error
type ResolutionError ΒΆ
type ResolutionError struct {
ServiceType reflect.Type
ServiceKey any // nil for non-keyed services
Cause error
}
ResolutionError wraps errors that occur during service resolution.
func (ResolutionError) Error ΒΆ
func (e ResolutionError) Error() string
func (ResolutionError) Unwrap ΒΆ
func (e ResolutionError) Unwrap() error
type Scope ΒΆ
type Scope interface {
ServiceProvider
// ID returns the unique ID of this scope.
ID() string
// Context returns the context associated with this scope.
Context() context.Context
// IsRootScope returns true if this provider is the root scope.
IsRootScope() bool
// Parent returns the parent scope of this scope.
Parent() Scope
}
Scope defines a disposable service scope. Scopes are used to control the lifetime of scoped services.
In web applications, a scope is typically created for each HTTP request, ensuring that services like database connections are properly managed and disposed at the end of the request.
Example:
scope := provider.CreateScope(ctx) defer scope.Close() scopedProvider := scope.ServiceProvider() service, err := godi.Resolve[MyService](scopedProvider)
type ScopeOption ΒΆ
type ScopeOption = dig.ScopeOption
ScopeOption modifies the default behavior of Scope creation.
type ServiceLifetime ΒΆ
type ServiceLifetime int
ServiceLifetime specifies the lifetime of a service in a ServiceCollection. The lifetime determines when instances are created and how they are cached. This maps to dig's scoping model while maintaining Microsoft DI semantics.
const ( // Singleton specifies that a single instance of the service will be created. // The instance is created on first request and cached for the lifetime of the root provider. // Singleton services must not depend on Scoped services. // In dig terms, this is a service provided at the root container level. Singleton ServiceLifetime = iota // Scoped specifies that a new instance of the service will be created for each scope. // In web applications, this typically means one instance per HTTP request. // Scoped services are disposed when their scope is disposed. // In dig terms, this is a service provided at the scope level. Scoped )
func (ServiceLifetime) IsValid ΒΆ
func (sl ServiceLifetime) IsValid() bool
IsValid checks if the service lifetime is valid.
func (ServiceLifetime) MarshalJSON ΒΆ
func (sl ServiceLifetime) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler.
func (ServiceLifetime) MarshalText ΒΆ
func (sl ServiceLifetime) MarshalText() ([]byte, error)
MarshalText implements encoding.TextMarshaler.
func (ServiceLifetime) String ΒΆ
func (sl ServiceLifetime) String() string
String returns the string representation of the ServiceLifetime.
func (*ServiceLifetime) UnmarshalJSON ΒΆ
func (sl *ServiceLifetime) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler.
func (*ServiceLifetime) UnmarshalText ΒΆ
func (sl *ServiceLifetime) UnmarshalText(text []byte) error
UnmarshalText implements encoding.TextUnmarshaler.
type ServiceProvider ΒΆ
type ServiceProvider interface {
// AddModules applies one or more module configurations to the service collection.
AddModules(modules ...ModuleOption) error
// AddSingleton registers a service with singleton lifetime.
// Only one instance is created and shared across all resolutions.
AddSingleton(constructor any, opts ...ProvideOption) error
// AddScoped registers a service with scoped lifetime.
// One instance is created per scope and shared within that scope.
AddScoped(constructor any, opts ...ProvideOption) error
// AddService registers a service with the specified lifetime.
AddService(lifetime ServiceLifetime, constructor any, opts ...ProvideOption) error
// Replace replaces all registrations of the specified service type.
Replace(lifetime ServiceLifetime, constructor any, opts ...ProvideOption) error
// RemoveAll removes all registrations of the specified service type.
RemoveAll(serviceType reflect.Type) error
// GetRootScope returns the root scope of the service provider.
// The root scope is used for singleton services and tracks disposal of singletons.
// It is also the default scope for resolving services.
// This scope is created automatically when the provider is built.
GetRootScope() Scope
// CreateScope creates a new service scope with the given context.
// The returned Scope is also a ServiceProvider for that scope.
CreateScope(ctx context.Context) Scope
// Resolve gets the service object of the specified type.
Resolve(serviceType reflect.Type) (any, error)
// ResolveKeyed gets the service object of the specified type with the specified key.
ResolveKeyed(serviceType reflect.Type, serviceKey any) (any, error)
// ResolveGroup gets all services of the specified type registered in a group.
// This is useful for plugin systems or when you need multiple implementations.
ResolveGroup(serviceType reflect.Type, groupName string) ([]any, error)
// IsService determines whether the specified service type is available.
// This is useful for optional dependencies.
IsService(serviceType reflect.Type) bool
// IsKeyedService determines whether the specified keyed service type is available.
IsKeyedService(serviceType reflect.Type, serviceKey any) bool
// Decorate provides a decorator for a type that has already been provided in the Scope.
Decorate(decorator any, opts ...DecorateOption) error
// Invoke executes a function with dependency injection.
// All parameters of the function are resolved from the container.
// The function can optionally return an error.
Invoke(function any) error
// IsDisposed returns true if the provider has been disposed.
IsDisposed() bool
Disposable
}
ServiceProvider is the main dependency injection container interface. It provides methods to resolve services, create scopes, and dynamically register services.
ServiceProvider is thread-safe and can be used concurrently. Services are resolved lazily on first request.
Example:
provider := godi.NewServiceProvider()
defer provider.Close()
// Register services dynamically
provider.AddSingleton(NewLogger)
provider.AddScoped(NewDatabase)
// Resolve a service
logger, err := godi.Resolve[Logger](provider)
if err != nil {
log.Fatal(err)
}
func DefaultServiceProvider ΒΆ
func DefaultServiceProvider() ServiceProvider
Default returns the current default ServiceProvider. Returns nil if no default provider has been set.
func NewServiceProvider ΒΆ
func NewServiceProvider() ServiceProvider
NewServiceProvider creates a new empty ServiceProvider that supports dynamic registration.
Example:
provider := godi.NewServiceProvider() provider.AddSingleton(NewLogger) provider.AddScoped(NewDatabase) defer provider.Close()
func NewServiceProviderWithOptions ΒΆ
func NewServiceProviderWithOptions(options *ServiceProviderOptions) ServiceProvider
NewServiceProviderWithOptions creates a new ServiceProvider with custom options.
type ServiceProviderOptions ΒΆ
type ServiceProviderOptions struct {
// OnServiceResolved is called after a service is successfully resolved.
// This can be used for logging, metrics, or debugging.
OnServiceResolved func(serviceType reflect.Type, instance any, duration time.Duration)
// OnServiceError is called when a service resolution fails.
// This can be used for error tracking and debugging.
OnServiceError func(serviceType reflect.Type, err error)
// ResolutionTimeout sets a timeout for individual service resolutions.
// 0 means no timeout (default).
ResolutionTimeout time.Duration
// DryRun when true, disables actual invocation of constructors (for testing).
DryRun bool
// RecoverFromPanics when true, recovers from panics in constructors.
RecoverFromPanics bool
// DeferAcyclicVerification defers cycle detection until first invoke.
DeferAcyclicVerification bool
}
ServiceProviderOptions configures various ServiceProvider behaviors.
type TimeoutError ΒΆ
TimeoutError indicates a service resolution timed out.
func (TimeoutError) Error ΒΆ
func (e TimeoutError) Error() string
func (TimeoutError) Is ΒΆ
func (e TimeoutError) Is(target error) bool
type TypeMismatchError ΒΆ
type TypeMismatchError struct {
Expected reflect.Type
Actual reflect.Type
Context string // "interface implementation", "type assertion", etc.
}
TypeMismatchError indicates a type assertion or conversion failed.
func (TypeMismatchError) Error ΒΆ
func (e TypeMismatchError) Error() string
type ValidationError ΒΆ
ValidationError indicates a validation failure.
func (ValidationError) Error ΒΆ
func (e ValidationError) Error() string