ComponentsLifecycle
Processors
Apply cross-cutting behavior before or after component initialization.
Processors wrap initialization for cross-cutting behavior. Use them for observability, validation, wrapping, or framework-level extension points.
type BeforeInitProcessor interface {
// ProcessBeforeInit runs before the component's Init method.
ProcessBeforeInit(ctx context.Context, name string, instance any) (any, error)
}
type LoggingInitProcessor struct{}
func (LoggingInitProcessor) ProcessBeforeInit(
ctx context.Context,
name string,
instance any,
) (any, error) {
log.Printf("initializing %s", name)
return instance, nil
}An after-init processor runs after the component has initialized.
type AfterInitProcessor interface {
// ProcessAfterInit runs after construction and Init have completed.
ProcessAfterInit(ctx context.Context, name string, instance any) (any, error)
}
type ReadyProcessor struct{}
func (ReadyProcessor) ProcessAfterInit(
ctx context.Context,
name string,
instance any,
) (any, error) {
log.Printf("%s initialized", name)
return instance, nil
}Both processors receive the component name and instance. They can validate, wrap, or replace the instance by returning a different value. Returning an error fails startup.
Processor guidance
- Use processors for cross-cutting behavior.
- Keep component-specific setup inside the component's
Initmethod. - Return the instance you want the container to continue using.
- Return an error when processing should fail startup.
