Skip to content

Proposal: way to automate invoke deps in do.Provider for any type constructor #67

@d-enk

Description

@d-enk
package main

import "github.com/samber/do/v2"


type Type struct {
	int
	uint64
	string
}

func NewType(i int, u uint64, s string) Type {
	return Type{i, u, s}
}


func main() {
	scope := do.New()

	do.ProvideValue(scope, int(1))
	do.ProvideValue(scope, uint64(2))
	do.ProvideValue(scope, string("str"))

	// instead
	do.Provide(scope, func(i do.Injector) (Type, error) {
		return NewType(
			do.MustInvoke[int](i),
			do.MustInvoke[uint64](i),
			do.MustInvoke[string](i),
		), nil
	})

	// something like
	do.ProvideAny[Type](scope, NewType)

	_ = do.MustInvoke[Type](scope)
}

Where

func ProvideAny[T any](i do.Injector, fun any) {
	fn := reflect.ValueOf(fun)
	
	// check that fn is func(...) T or func(...) (T, error)

	do.Provide[T](i, func(i do.Injector) (res T, err error) {
		inputTypes := []reflect.Value{}
		// inputTypes - invoked input by type name

		out := fn.Call(inputTypes)

		// res = out[0]
		// err = out[1]

		return
	})
}

Also the function can have variadic names ... string
With a match for each function parameter, to use it instead of the type name.
Analog do:"name" in struct

If interested I can send pull request.
We can discuss the interface.

Now it just

func ToProvider[T any](fun any) do.Provider[T]

do.Provide(scope, ToProvider[Type](NewType))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions