go-kod / kod

A generics based dependency injection application framework for Go, support OpenTelemetry trace/metric/log natively 🚀🚀🚀
https://pkg.go.dev/github.com/go-kod/kod
Apache License 2.0
109 stars 3 forks source link

Multi kod.Main implements supported? #168

Closed leopku closed 4 weeks ago

leopku commented 1 month ago

My app was a command-line app based on cobra and had many sub commands as different entrances.

type demo1Impl struct {
    kod.Implements[kod.Main]
    db kod.Ref[db.Component]
}

...
type demo2Impl struct {
    kod.Implements[kod.Main]
    db kod.Ref[db.Component]
}

...

result as

Error: components [github.com/go-kod/kod/Main], error vertex already exists
sysulq commented 1 month ago

I would think about it, thanks for the suguestion

sysulq commented 1 month ago

@leopku I would like to add lazy init feature to support multiple cmd component in one kod.Main,without the need to init unused resources,which would be nice for this situation,what do you think?

leopku commented 1 month ago

@leopku I would like to add lazy init feature to support multiple cmd component in one kod.Main,without the need to init unused resources,which would be nice for this situation,what do you think?

Sounds great. Hoping to test it.

sysulq commented 1 month ago

@leopku I created a pr #169 for this lazy init feature, could you help to test it to check if everything works fine, thanks~

leopku commented 4 weeks ago

@sysulq I'm testing it now. Feedback will be A.S.A.P.

leopku commented 4 weeks ago

kod.LazyInit was added to both two demoImpl, but error Error: components [github.com/go-kod/kod/Main], error vertex already exists wasn't changed.

any advice?

sysulq commented 4 weeks ago

@leopku Do not create two kod.Main, try like this:

type app struct {
  kod.Implemenets[kod.Main]
  cmd1 kod.Ref[Cmd1]
  cmd2 kod.Ref[Cmd2]
}

type cmd1 struct {
  kod.Implemenets[Cmd1]
  kod.LazyInit
}

type cmd2 struct {
  kod.Implemenets[Cmd2]
  kod.LazyInit
}

And you can call cmd1 or cmd2 in each cobra subcommand, without the need to initial another cmd component at the same time.

leopku commented 4 weeks ago

When I running kod generate -s ./..., I got error as below,

[struct2interface] 1.885103ms
-: # github.com/leopku/kodtest/cmd
cmd/kod_gen_interface.go:10:6: IMigration redeclared in this block
        cmd/demo2.go:15:6: other declaration of IMigration
cmd/demo2.go:41:17: *demo2Impl does not satisfy kod.PointerToMain[demo2Impl] (wrong type for method implements)
                have implements(IMigration)
                want implements(kod.Main)
/Users/leo/Project/go/kodtest/cmd/kod_gen_interface.go:10:6: IMigration redeclared in this block
/Users/leo/Project/go/kodtest/cmd/demo2.go:15:6:        other declaration of IMigration
/Users/leo/Project/go/kodtest/cmd/demo2.go:41:10: *demo2Impl does not satisfy kod.PointerToMain[demo2Impl] (wrong type for method implements)
                have implements(IMigration)
                want implements(kod.Main)

Demo codes was uploaded to https://github.com/leopku/kodtest

sysulq commented 4 weeks ago

You can give me write permission for this repo, and I would make it through :-)

leopku commented 4 weeks ago

@sysulq invite sent.

sysulq commented 4 weeks ago

@leopku done

leopku commented 4 weeks ago

Thanks a lot. I misunderstood the usage. Interface can be used in kod.Implements without pre-defined, amazing...

sysulq commented 4 weeks ago

Yep, and you can even run kod generate -s -w ./... to watch the changes, and kod would rerun generate automatically when changes happen :-)

With kod, we don't need to care about how to create/bind these components, so we can focus more on component design and test cases. Enjoy it and hope more feedbacks~

leopku commented 4 weeks ago

Amazing and issue closed

leopku commented 4 weeks ago

@sysulq Failed for simple complex case when ref from another package. Details see demo2 in https://github.com/leopku/kodtest

$ kod generate -s ./...
$ go run main.go demo2

result as

Error: component implementation struct cmd.demo2Impl has field kod.Ref[github.com/leopku/kodtest/pkg/migrate.Migrate], but component migrate.Migrate was not registered; maybe you forgot to run 'kod generate'
exit status 1
sysulq commented 4 weeks ago

@leopku kod.Ref only support interface, instead of struct. You can checkout the latest version.

leopku commented 4 weeks ago

aah, got it.