do icon indicating copy to clipboard operation
do copied to clipboard

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

Open d-enk opened this issue 10 months ago • 2 comments

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))

d-enk avatar Apr 26 '24 16:04 d-enk

Yes, it has been discussed already.

I'm adding this proposal to v2.1 release.

See https://github.com/samber/do/pull/28

samber avatar May 05 '24 19:05 samber

Yes, it has been discussed already.

There is nothing about calculating constructor function arguments.

Here we are talking about the possibility of turning a "native" constructor into Provider

d-enk avatar May 06 '24 08:05 d-enk