Provide & Inject
Components can share values with their descendants without passing them explicitly through props. A parent calls Provide to expose a value, and nested components can access it with Inject.
Providing a Value
Call Provide inside a lifecycle hook such as OnMount to make a value available to child components:
func (c *ParentComponent) OnMount() {
c.Provide("user", "Ada")
}
Injecting a Value
Use Inject to search up the component tree for a matching key:
name, ok := core.Inject[string](c, "user")
if ok {
// use name
}
If no provider is found, ok is false.
DI Container Injection
rfw v2 supports dependency injection via *t.Inject[T] struct fields and the composition.Container():
// Register a dependency globally
composition.Container().Provide("logger", myLogger)
// Inject into a struct field
type MyPage struct {
composition.Component
Logger *t.Inject[Logger]
}
When composition.New(&MyPage{}) is called, *t.Inject[T] fields are automatically resolved from the container using the lowercase field name as the key. The Logger field above resolves from Container().Get("logger").
Custom keys work by renaming the field:
type Page struct {
composition.Component
AppLog *t.Inject[Logger] // resolves from Container().Get("applog")
}
Full Example
parent := core.NewComponent("Parent", parentTpl, nil)
child := core.NewComponent("Child", childTpl, nil)
parent.Provide("answer", 42)
parent.AddDependency("child", child)
answer, _ := core.Inject[int](child, "answer") // 42
When to Use
- Provide/Inject for values that flow down the component tree (parent → child).
*t.Inject[T]field for global singletons and services registered in the container.