Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@zhulik
Copy link
Owner

@zhulik zhulik commented Sep 28, 2025

Now instead invoking factory services manually with pal.Invoke, you can inject factory functions. They are safe to use from Init() methods as pal can figure out the correct initialization order.
Example:

package main

import (
        "context"
        "log/slog"
        "os"
        "testing"
        "time"

        "github.com/zhulik/pal"
        "github.com/zhulik/pal/inspect"
)

type Heartbeater interface {
        Heartbeat(ctx context.Context)
}

type heartbeater struct {
}

func (h *heartbeater) Init(ctx context.Context) error {
        h.Logger.InfoContext(ctx, "Heartbeater initialized")
        return nil
}

func (h *heartbeater) Heartbeat(ctx context.Context) {
        h.Logger.InfoContext(ctx, "Heartbeat")
}

type mainRunner struct {
        Logger            *slog.Logger
        CreateHeartbeater func(ctx context.Context, count int) (Heartbeater, error) // <-- Injected factory function

        heartbeater Heartbeater
}

func (m *mainRunner) Init(ctx context.Context) error {
        m.Logger.InfoContext(ctx, "MainRunner initialized")

        heartbeater, err := m.CreateHeartbeater(ctx, 0)
        if err != nil {
                return err
        }
        m.heartbeater = heartbeater

        return nil
}

func (m *mainRunner) Run(ctx context.Context) error {
        for {
                select {
                case <-ctx.Done():
                        return ctx.Err()
                case <-time.After(time.Second):
                        m.heartbeater.Heartbeat(ctx)
                }
        }
}

func main() {
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
        slog.SetDefault(logger)

        err := pal.New(
                pal.Provide(&mainRunner{}),
                inspect.Provide(),
                pal.ProvideFactory1[Heartbeater](func(_ context.Context, count int) (*heartbeater, error) {
                        return &heartbeater{count: count}, nil
                }),
        ).
                InjectSlog().
                InitTimeout(time.Second).
                HealthCheckTimeout(time.Second).
                ShutdownTimeout(time.Second).
                Run(t.Context())
        if err != nil {
                panic(err)
        }
}

@zhulik zhulik merged commit 01abb84 into main Sep 28, 2025
3 checks passed
@zhulik zhulik deleted the inject-factory-functions branch September 28, 2025 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant