Vormia Go Core
Lightweight foundation for building scalable Go applications.
vormia-go-core provides essential infrastructure patterns used by the entire Vormia ecosystem: dependency injection, configuration management, logging, event dispatching, lifecycle hooks, context values, and error handling.
Stdlib only — no HTTP frameworks, no database drivers, no third-party dependencies.
Features
- Dependency Injection Container — Register and resolve services (singleton or transient)
- Configuration Management — Load from
.env files and OS environment
- Logger Interface — Stdout and file loggers with level filtering
- Event System — Sync and async publish/subscribe
- Lifecycle Hooks — Ordered boot and shutdown (with signal handling)
- Context Management — Typed keys and request-scoped value bags
- Error Handling — Wrapping, rich
Exception type, logging handler
Installation
go get github.com/vormialabs/vormia-go-core@v0.0.1
Quick Start
Dependency Injection
package main
import (
"fmt"
"github.com/vormialabs/vormia-go-core/container"
)
type UserRepository struct{}
func (r *UserRepository) GetUser(id string) string {
return "User: " + id
}
func main() {
c := container.New()
// Singleton (factory runs once)
c.Register("userRepo", func() interface{} {
return &UserRepository{}
})
repo, _ := c.Resolve("userRepo")
userRepo := repo.(*UserRepository)
fmt.Println(userRepo.GetUser("123"))
// Output: User: 123
}
Configuration
package main
import (
"fmt"
"github.com/vormialabs/vormia-go-core/config"
)
func main() {
cfg := config.New()
_ = cfg.Load(".env") // missing file is OK
cfg.LoadEnv() // OS env wins over file values
dbHost := cfg.GetString("DB_HOST", "localhost")
dbPort := cfg.GetInt("DB_PORT", 5432)
fmt.Printf("Connecting to %s:%d\n", dbHost, dbPort)
}
Logging
package main
import (
"errors"
"github.com/vormialabs/vormia-go-core/logger"
)
func main() {
log := logger.NewStdoutLogger()
log.SetLevel(logger.LevelDebug)
log.Info("Application started", map[string]interface{}{
"version": "0.0.1",
})
log.Error("Something went wrong", errors.New("boom"), map[string]interface{}{
"userId": 123,
})
}
Events
package main
import (
"fmt"
"github.com/vormialabs/vormia-go-core/events"
)
func main() {
dispatcher := events.NewDispatcher()
dispatcher.Listen("user.created", func(payload interface{}) {
fmt.Println("User created:", payload)
})
dispatcher.Dispatch("user.created", map[string]string{
"userId": "123",
"email": "user@example.com",
})
}
Application Lifecycle
package main
import (
"fmt"
"github.com/vormialabs/vormia-go-core/lifecycle"
)
func main() {
app := lifecycle.NewApp()
app.OnBoot(func() error {
fmt.Println("Loading config...")
fmt.Println("Connecting to database...")
return nil
})
app.OnShutdown(func() error {
fmt.Println("Closing connections...")
return nil
})
if err := app.Boot(); err != nil {
panic(err)
}
defer app.Shutdown()
// Or block until Ctrl+C / SIGTERM:
// app.WaitForSignal()
}
Core Interfaces
Container
type ServiceContainer interface {
Register(name string, factory func() interface{}) error
Resolve(name string) (interface{}, error)
Get(name string, defaultValue interface{}) interface{}
}
Also: RegisterTransient, Has, ServiceProvider, RegisterProviders.
Config
// *config.Config methods:
Get(key string) interface{}
Set(key string, value interface{})
Load(path string) error
LoadEnv()
GetString(key, def string) string
GetInt(key string, def int) int
GetBool(key string, def bool) bool
Require(keys ...string) error
Logger
type Logger interface {
Debug(message string, context map[string]interface{})
Info(message string, context map[string]interface{})
Warn(message string, context map[string]interface{})
Error(message string, err error, context map[string]interface{})
SetLevel(level Level)
}
Implementations: NewStdoutLogger(), NewFileLogger(path).
EventDispatcher
type EventDispatcher interface {
Listen(event string, callback func(payload interface{}))
Dispatch(event string, payload interface{})
}
Also: ListenTo, DispatchAsync, Forget, HasListeners.
Package Structure
vormia-go-core/
├── go.mod
├── README.md
├── container/ # DI container + ServiceProvider
├── config/ # Config store, .env loader, Require()
├── logger/ # Logger interface, stdout + file
├── events/ # Dispatcher, Listener, async emit
├── lifecycle/ # App boot/shutdown hooks + signals
├── context/ # Typed keys + ValueBag
└── errors/ # Wrap, Exception, Handler
Testing
go test ./...
go vet ./...
Use Cases
Use vormia-go-core if you need:
- Dependency injection without external frameworks
- Simple but powerful configuration management
- Unified logging across your application
- Event-driven architecture
- Application lifecycle management
- Foundation for building larger frameworks
Standalone usage: Absolutely. You can use core in any Go application.
With Vormia Framework: This is the foundation for vormia-go, which adds HTTP routing, auth, validation, database, cache, and more.
License
See LICENSE.