Top Related Projects
Quick Overview
samber/do
is a dependency injection toolkit for Go, designed to simplify the management of dependencies in Go applications. It provides a lightweight and flexible approach to dependency injection, allowing developers to write more modular and testable code.
Pros
- Lightweight and easy to use, with minimal boilerplate code
- Supports both singleton and transient dependencies
- Allows for easy mocking and testing of components
- Type-safe dependency resolution at compile-time
Cons
- Requires some initial setup and understanding of dependency injection concepts
- May introduce a small performance overhead compared to manual dependency management
- Limited documentation and community support compared to more established DI frameworks
- Potential for circular dependencies if not carefully managed
Code Examples
- Defining and resolving a dependency:
type Database struct{}
func NewDatabase() *Database {
return &Database{}
}
container := do.New()
container.AddSingleton(NewDatabase)
db := do.MustInvoke[*Database](container)
- Using interfaces for dependency injection:
type Logger interface {
Log(message string)
}
type ConsoleLogger struct{}
func (l *ConsoleLogger) Log(message string) {
fmt.Println(message)
}
container.AddSingleton(func() Logger {
return &ConsoleLogger{}
})
logger := do.MustInvoke[Logger](container)
logger.Log("Hello, World!")
- Injecting dependencies into a struct:
type Service struct {
DB *Database `inject:""`
Logger Logger `inject:""`
}
container.AddSingleton(func(db *Database, logger Logger) *Service {
return &Service{DB: db, Logger: logger}
})
service := do.MustInvoke[*Service](container)
Getting Started
To start using samber/do
in your Go project:
-
Install the package:
go get github.com/samber/do
-
Import the package in your code:
import "github.com/samber/do"
-
Create a new container and start adding dependencies:
container := do.New() container.AddSingleton(NewDatabase) container.AddSingleton(func() Logger { return &ConsoleLogger{} })
-
Resolve dependencies when needed:
db := do.MustInvoke[*Database](container) logger := do.MustInvoke[Logger](container)
Competitor Comparisons
A dependency injection based application framework for Go.
Pros of fx
- More mature and widely adopted project with extensive documentation
- Provides a complete dependency injection framework with lifecycle management
- Offers advanced features like parameter objects and optional dependencies
Cons of fx
- Steeper learning curve due to more complex API and concepts
- Requires more boilerplate code for setup and configuration
- Heavier runtime overhead compared to simpler alternatives
Code Comparison
fx:
func NewHandler(lc fx.Lifecycle, logger *zap.Logger) *Handler {
handler := &Handler{logger: logger}
lc.Append(fx.Hook{
OnStart: func(context.Context) error {
// Initialization logic
return nil
},
})
return handler
}
do:
func NewHandler(logger *zap.Logger) *Handler {
return &Handler{logger: logger}
}
// Usage
handler := do.MustInvoke[*Handler](container)
Summary
fx is a more comprehensive dependency injection framework with advanced features and lifecycle management, suitable for larger projects. do offers a simpler, lightweight alternative with less overhead and easier setup, making it ideal for smaller applications or those preferring a minimalist approach. The choice between the two depends on project complexity, team familiarity, and specific requirements for dependency management and application structure.
Compile-time Dependency Injection for Go
Pros of Wire
- Generates code at compile-time, reducing runtime overhead
- Backed by Google, potentially offering more long-term support
- Provides clear error messages for dependency issues
Cons of Wire
- Requires a separate code generation step
- Less flexible for runtime configuration changes
- Steeper learning curve for newcomers to dependency injection
Code Comparison
Wire:
func InitializeEvent(w http.ResponseWriter, r *http.Request) (*Event, error) {
wire.Build(NewEvent, NewGreeter, NewMessage)
return nil, nil
}
Do:
container := do.New()
container.Provide(NewEvent)
container.Provide(NewGreeter)
container.Provide(NewMessage)
event := container.Get((*Event)(nil))
Summary
Wire focuses on compile-time dependency injection, offering performance benefits but less runtime flexibility. Do provides a more traditional runtime dependency injection approach, allowing for easier dynamic configuration but with potential runtime overhead. Wire's code generation may be preferable for larger projects with stable dependencies, while Do's simplicity might be more suitable for smaller projects or those requiring frequent runtime changes. The choice between the two depends on specific project requirements and developer preferences.
Package inject provides a reflect based injector.
Pros of inject
- More mature and battle-tested, having been used in production at Facebook
- Supports more advanced features like optional dependencies and provider overrides
- Has a larger community and ecosystem of extensions and integrations
Cons of inject
- No longer actively maintained (archived repository)
- More complex API and steeper learning curve
- Heavier and potentially slower due to more features
Code Comparison
inject:
type Server struct {
Port int `inject:""`
DB *sql.DB `inject:""`
}
var server Server
injector.Inject(&server)
do:
type Server struct {
Port int
DB *sql.DB
}
server := do.MustInvoke[Server](container)
Summary
inject is a more feature-rich and mature dependency injection framework, but it's no longer maintained. do offers a simpler, more modern approach with a focus on type safety and ease of use. While inject may be better suited for complex, large-scale applications, do is likely a better choice for new projects due to its active development and straightforward API.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
do - Dependency Injection
âï¸ A dependency injection toolkit based on Go 1.18+ Generics.
This library implements the Dependency Injection design pattern. It may replace the fantastic uber/dig
package. samber/do
uses Go 1.18+ generics and therefore offers a typeâsafe API.
See also:
- samber/lo: A Lodash-style Go library based on Go 1.18+ Generics
- samber/mo: Monads based on Go 1.18+ Generics (Option, Result, Either...)
Why this name?
I love the short name for such a utility library. This name is the sum of DI
and Go
and no Go package uses this name.
ð¡ Features
- ð Service registration
- Register by type
- Register by name
- Register multiple services from a package at once
- ðª Service invocation
- Eager loading
- Lazy loading
- Transient loading
- Tag-based invocation
- Circular dependency detection
- ð§ââï¸ Service aliasing
- Implicit (provide struct, invoke interface)
- Explicit (provide struct, bind interface, invoke interface)
- ð Service lifecycle
- Health check
- Graceful unload (shutdown)
- Dependency-aware parallel shutdown
- Lifecycle hooks
- ð¦ Scope (a.k.a module) tree
- Visibility control
- Dependency grouping
- ð¤ Container
- Dependency graph resolution and visualization
- Default container
- Container cloning
- Service override
- 𧪠Debugging & introspection
- Explain APIs: scope tree and service dependencies
- Web UI & HTTP middleware (std, Gin, Fiber, Echo, Chi)
- ð Lightweight, no dependencies
- ð No code generation
- ð· Typeâsafe API
ð Install
# v2 (latest)
go get github.com/samber/do@v2
# v1
go get github.com/samber/do@v1.6.0
This library is v2 and follows SemVer strictly.
No breaking changes will be made to exported APIs before v3.0.0.
This library has no dependencies except the Go std lib.
ð¥ Migration from v1 to v2
ð¤ Documentation
ð¬ Project boilerplate
ð¤ Contributing
- Ping me on Twitter @samuelberthe (DMs, mentions, whatever :))
- Fork the project
- Fix open issues or request new features
Don't hesitate ;)
# Install some dev dependencies
make tools
# Run tests
make test
# or
make watch-test
ð¤ Contributors
ð« Show your support
Give a âï¸ if this project helped you!
ð License
Copyright © 2022 Samuel Berthe.
This project is MIT licensed.
Top Related Projects
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot