Write a Provider
Implement the Provider lifecycle
Provider is the only protocol for connecting extensions to Runa. It registers your objects in DI, reads config, registers commands, registers Host units, and joins startup and shutdown.
Regular business code should prefer Module and usually does not need to implement Provider. Write a Provider only when developing reusable capability packages, driver adapters, transport blocks, or third-party extensions.
Start with a minimal Provider
package hello
import (
"context"
"github.com/duxweb/runa/provider"
"github.com/samber/do/v2"
)
type Service struct {
Message string
}
func New(message string) *Service {
return &Service{Message: message}
}
func Provider(message string) provider.Provider {
return providerImpl{message: message}
}
type providerImpl struct {
provider.Base
message string
}
func (providerImpl) Name() string { return "hello" }
func (p providerImpl) Init(_ context.Context, ctx provider.Context) error {
provider.ProvideDefault(ctx, func(do.Injector) (*Service, error) {
return New(p.message), nil
})
return nil
}
Use it in an application
app := runa.New()
app.Install(hello.Provider("Hello Runa"))
if err := app.Freeze(context.Background()); err != nil {
panic(err)
}
service := runa.MustInvoke[*hello.Service]()
What each lifecycle stage should do
- Register DI constructors in
Init. - Read config, register commands, and register instances in
Register. - Install business modules through
RegisterModuleinRegisterwhen needed. - Do startup logic that requires all Providers to be registered in
Boot. - Close external connections in
Shutdown. - Do not import
runtimeinside a Provider.
Register business modules
A Provider can mount business modules shipped with an extension, but application-specific business modules usually use app.Module(...) directly.
func (p providerImpl) Register(ctx provider.Context) error {
return ctx.RegisterModule(hello.Module{})
}
Register commands during Register
func (p providerImpl) Register(ctx provider.Context) error {
return ctx.RegisterCommand(command{})
}
Acceptance checklist
go test ./...passes.- The application can start after
Install(provider). Default()or DI can retrieve the core object.Shutdownreleases resources.