123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- package di
- import (
- "reflect"
- "kpt-tmr-group/pkg/cleanup"
- "kpt-tmr-group/pkg/di/xreflect"
- "kpt-tmr-group/pkg/xerr"
- "go.uber.org/dig"
- )
- func New(opts ...HubOption) (*Hub, error) {
- hub := &Hub{
- cleanup: cleanup.Entry{},
- provides: make([]Provided, 0),
- }
- for _, opt := range opts {
- opt.Apply(hub)
- }
- hub.container = dig.New(
- dig.DryRun(hub.validate),
- )
- for i, p := range hub.provides {
- if err := hub.usingProvide(p); err != nil {
- return nil, xerr.Errorf("error after options[%d] were applied: %v", i, err)
- }
- }
- return hub, nil
- }
- type Hub struct {
- container *dig.Container
- cleanup cleanup.Entry
- provides []Provided
- validate bool
- }
- func (hub *Hub) Cleanup() {
- hub.cleanup.Run()
- }
- type Provided struct {
-
- Target interface{}
-
- Stack xreflect.Stack
-
- IsSupply bool
- }
- func (hub *Hub) usingProvide(p Provided) error {
- constructor := p.Target
- if _, ok := constructor.(HubOption); ok {
- return xerr.Errorf("di.Option should be passed to di.New directly, "+
- "not to di.Provide: di.Provide received %v from:\n%+v",
- constructor, p.Stack)
- }
- if ann, ok := constructor.(Annotated); ok {
- var opts []dig.ProvideOption
- switch {
- case len(ann.Group) > 0 && len(ann.Name) > 0:
- return xerr.Errorf(
- "di.Annotated may specify only one of Name or Group: received %v from:\n%+v",
- ann, p.Stack)
- case len(ann.Name) > 0:
- opts = append(opts, dig.Name(ann.Name))
- case len(ann.Group) > 0:
- opts = append(opts, dig.Group(ann.Group))
- }
-
- if err := hub.Provide(ann.Target, opts...); err != nil {
- return xerr.Errorf("di.Provide(%v) from:\n%+vFailed: %v", ann, p.Stack, err)
- }
-
- if ann.Close != nil {
- hub.cleanup.Register(ann.Close)
- }
- return nil
- }
- if reflect.TypeOf(constructor).Kind() == reflect.Func {
- ft := reflect.ValueOf(constructor).Type()
- for i := 0; i < ft.NumOut(); i++ {
- t := ft.Out(i)
- if t == reflect.TypeOf(Annotated{}) {
- return xerr.Errorf(
- "di.Annotated should be passed to di.Provide directly, "+
- "it should not be returned by the constructor: "+
- "di.Provide received %v from:\n%+v",
- xreflect.FuncName(constructor), p.Stack)
- }
- }
- }
- if err := hub.Provide(constructor); err != nil {
- return xerr.Errorf("di.Provide(%v) from:\n%+vFailed: %v", xreflect.FuncName(constructor), p.Stack, err)
- }
- return nil
- }
- func (hub *Hub) Invoke(function interface{}, opts ...InvokeOption) error {
- return hub.container.Invoke(function, opts...)
- }
- func (hub *Hub) Provide(constructor interface{}, opts ...ProvideOption) error {
- return hub.container.Provide(constructor, opts...)
- }
- func (hub *Hub) GetProvidedSlice() []Provided {
- return hub.provides
- }
|