Installation01
go get github.com/xraph/vesselMinimal Setup02
package main
import (
"context"
"fmt"
"log"
"github.com/xraph/vessel"
)
type Database struct {
DSN string
}
func (d *Database) Name() string { return "database" }
func (d *Database) Start(ctx context.Context) error { fmt.Println("DB connected"); return nil }
func (d *Database) Stop(ctx context.Context) error { fmt.Println("DB disconnected"); return nil }
type UserService struct {
db *Database
}
func main() {
c := vessel.New()
// Register constructors -- dependencies resolved by Go type
vessel.Provide(c, func() *Database {
return &Database{DSN: "postgres://localhost:5432/app"}
})
vessel.Provide(c, func(db *Database) *UserService {
return &UserService{db: db}
})
// Resolve by type
userService, err := vessel.Inject[*UserService](c)
if err != nil {
log.Fatal(err)
}
fmt.Printf("UserService uses DB at %s\n", userService.db.DSN)
// Start all services (respects dependency order)
ctx := context.Background()
if err := c.Start(ctx); err != nil {
log.Fatal(err)
}
defer c.Stop(ctx)
}Why This Pattern03
Dependencies are resolved by Go type, not string keys.
Constructors are plain functions -- easy to test and reason about.
Registration stays close to actual object construction.
Refactors are safer because types are checked at compile time.
The container starts and stops services in topological order.
Alternative: Named Registration04
When you need explicit names (for multiple instances of the same type, or compatibility with existing code), use ProvideNamed:
c := vessel.New()
vessel.ProvideNamed(c, "database", func() (*Database, error) {
return &Database{DSN: "postgres://localhost:5432/app"}, nil
}, vessel.AsSingleton())
db, err := vessel.InjectNamed[*Database](c, "database")You can also register a pre-built value:
cfg := &AppConfig{Port: 8080}
vessel.ProvideValue(c, cfg, vessel.WithName("config"))
config, err := vessel.InjectNamed[*AppConfig](c, "config")Next Steps05
Constructors --
In/Outstructs, named instances, groupsLifetimes and Scopes -- singleton, transient, scoped
Forge Integration -- using Vessel inside a Forge application