https://github.com/4strodev/wiring
A dependency injection and autowiring library
https://github.com/4strodev/wiring
autowiring container dependency-injection go reflection
Last synced: 9 months ago
JSON representation
A dependency injection and autowiring library
- Host: GitHub
- URL: https://github.com/4strodev/wiring
- Owner: 4strodev
- License: mit
- Created: 2024-09-30T13:39:58.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2025-01-09T22:18:16.000Z (over 1 year ago)
- Last Synced: 2025-01-09T22:32:27.289Z (over 1 year ago)
- Topics: autowiring, container, dependency-injection, go, reflection
- Language: Go
- Homepage:
- Size: 81.1 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
## Deprecated
If anyone uses this library I have to tell you that is going to be deprecated. It lacks a set of basic functionalities
and the implementation is not well designed. I started a new implementation [here](https://github.com/4strodev/wiring-graphs).
[](https://pkg.go.dev/github.com/4strodev/wiring)


# ๐ Wiring
A container for DI and autowiring written in Go. The main purpose is to provide an interface and a default implementation
for autowiring. You can use the default implementation or create your own if the requirements of your project are not
satisfied.
## Download
go get github.com/4strodev/wiring@latest
# ๐ Features
Yet this library tries to be as simple as possible I tried to create the minimum features to cover the majority of usecases.
## Lifecycle
There are two kind of lifecycles
- **Singleton**: These dependencies are instantiated once and then the instance is cached for future resolves.
- The default implementation is **๐งต concurrently safe**.
- **Transient**: Those are dependencies that are always instantiated every time they are resolved.
- **Scoped**: For scoped dependencies take a look to the `extended` package.
### Ej. Resolve a dependency
```go
package main
import (
"fmt"
wiring "github.com/4strodev/wiring/pkg"
)
type Abstraction interface {
Greet()
}
type Implementation struct {
}
func (i *Implementation) Greet() {
fmt.Println("Hello world")
}
func main() {
var container = wiring.New()
container.Singleton(func() (Abstraction, error) {
// This resolver is executed just once
fmt.Println("Running resolver")
return &Implementation{}, nil
})
// Resolving dependency
var impl Abstraction
container.Resolve(&impl)
impl.Greet()
var otherImpl Abstraction
container.Resolve(&otherImpl)
otherImpl.Greet()
// Output:
// Running resolver
// Hello world
// Hello world
}
```
## Extended containers
The `extended` package contains extensions for containers:
- **Derived**: A derived container allows you to create containers that inherits resolvers from parent containers. This is a fully functional container which can has their own and *Scoped ๐* dependencies.
Allowing you to use container for short living contexts like an http request.
- **Must**: An interface that instead of returning errors panics.
## Token based
Token based dependencies allows you to specify dependencies using a custom token. These are performant, because they are not relying in reflection (at all), and allows you to have
multiple dependencies of the same type but with different tokens.
### Ej. Resolving a dependency
```go
package main
import (
"fmt"
wiring "github.com/4strodev/wiring/pkg"
)
type Abstraction interface {
Greet()
}
type Implementation struct {
}
func (i *Implementation) Greet() {
fmt.Println("Hello world")
}
func main() {
var container = wiring.New()
err := container.TransientToken("abstraction", func() (Abstraction, error) {
return &Implementation{}, nil
})
if err != nil {
panic(err)
}
var impl Abstraction
err = container.ResolveToken("abstraction", &impl)
if err != nil {
panic(err)
}
impl.Greet()
}
```
## Struct filling
Do you have massive dependencies? No problem define a struct with exported fields and let the container fill your struct with the dependencies you need.
```go
package main
import (
"fmt"
"log"
wiring "github.com/4strodev/wiring/pkg"
)
type Abstraction interface {
Greet()
}
type Implementation struct {
}
func (i *Implementation) Greet() {
fmt.Println("Hello world")
}
type FillableStruct struct {
Greeter Abstraction // if no tag is specified it is resolved by type
TokenBased Abstraction `wire:"token"`
IgnoredReader io.Reader `wire:",ignore"`
ignoredField string
}
func main() {
var container = wiring.New()
container.Singleton(func() (Abstraction, error) {
// This resolver is executed just once
return &Implementation{}, nil
})
container.SingletonToken("token", func() (Abstraction, error) {
// This resolver is executed just once
return &Implementation{}, nil
})
var fillable FillableStruct
err := container.Fill(&fillable)
if err != nil {
log.Fatal(err)
}
fillable.Greeter.Greet()
fillable.TokenBased.Greet()
}
```
## Docs
There are more examples on [the documentation](https://pkg.go.dev/github.com/4strodev/wiring)
## Inspiration
This project was heavily inspired by [goloby/container](https://github.com/golobby/container).