-
-
Notifications
You must be signed in to change notification settings - Fork 8
Apply to struct without connect #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,41 +57,9 @@ func New() Container { | |
| } | ||
| } | ||
|
|
||
| // Connect a component, optionally identified by id. | ||
| func (container Container) Connect(val interface{}, id ...string) { | ||
| ptr := false | ||
| rv := reflect.ValueOf(val) | ||
| rt := rv.Type() | ||
| nam := "" | ||
| _, file, no, _ := runtime.Caller(container.callerSkip + 1) | ||
|
|
||
| if len(id) > 0 { | ||
| nam = id[0] | ||
| } | ||
|
|
||
| comp := component{ | ||
| id: nam, | ||
| value: rv, | ||
| declaredAt: file + ":" + strconv.Itoa(no), | ||
| } | ||
|
|
||
| if rt.Kind() == reflect.Ptr { | ||
| rt = rt.Elem() | ||
| rv = rv.Elem() | ||
| comp.value = rv | ||
| ptr = true | ||
| } | ||
|
|
||
| if gr, ok := container.components[rt]; ok { | ||
| if comp, ok := gr.find(nam); ok { | ||
| panic(duplicateError{previous: comp}) | ||
| } | ||
| } | ||
| func dependinces(container Container, rt reflect.Type, rv reflect.Value) []dependency { | ||
|
|
||
| if rt.Kind() != reflect.Struct { | ||
| container.components[rt] = append(container.components[rt], comp) | ||
| return | ||
| } | ||
| dependinces := make([]dependency, 0) | ||
|
|
||
| for i := 0; i < rt.NumField(); i++ { | ||
| sf := rt.Field(i) | ||
|
|
@@ -121,15 +89,17 @@ func (container Container) Connect(val interface{}, id ...string) { | |
| impl = idAndImpl[1] | ||
| } | ||
|
|
||
| comp.dependencies = append(comp.dependencies, dependency{ | ||
| dependinces = append(dependinces, dependency{ | ||
| id: id, | ||
| name: sf.Name, | ||
| index: i, | ||
| typ: depRt, | ||
| impl: impl, | ||
| }) | ||
|
|
||
| } else if (sf.Type.Kind() == reflect.Ptr || sf.Type.Kind() == reflect.Interface) && rv.Field(i).IsNil() { | ||
| panic(tagMissingError{field: sf}) | ||
| // Is this required | ||
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trying to use an external library where
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is for validation purpose, to ensure all dependency is properly added and connected. Hmm, I never consider the case where external library might have nil pointer or interface. |
||
| // panic(tagMissingError{field: sf}) | ||
| } else if sf.Type.Kind() == reflect.Struct { | ||
| // check forgotten tag only for struct. | ||
| if _, exist := container.components[sf.Type]; exist { | ||
|
|
@@ -138,6 +108,47 @@ func (container Container) Connect(val interface{}, id ...string) { | |
| } | ||
| } | ||
|
|
||
| return dependinces | ||
| } | ||
|
|
||
| // Connect a component, optionally identified by id. | ||
| func (container Container) Connect(val interface{}, id ...string) { | ||
| ptr := false | ||
| rv := reflect.ValueOf(val) | ||
| rt := rv.Type() | ||
| nam := "" | ||
| _, file, no, _ := runtime.Caller(container.callerSkip + 1) | ||
|
|
||
| if len(id) > 0 { | ||
| nam = id[0] | ||
| } | ||
|
|
||
| comp := component{ | ||
| id: nam, | ||
| value: rv, | ||
| declaredAt: file + ":" + strconv.Itoa(no), | ||
| } | ||
|
|
||
| if rt.Kind() == reflect.Ptr { | ||
| rt = rt.Elem() | ||
| rv = rv.Elem() | ||
| comp.value = rv | ||
| ptr = true | ||
| } | ||
|
|
||
| if gr, ok := container.components[rt]; ok { | ||
| if comp, ok := gr.find(nam); ok { | ||
| panic(duplicateError{previous: comp}) | ||
| } | ||
| } | ||
|
|
||
| if rt.Kind() != reflect.Struct { | ||
| container.components[rt] = append(container.components[rt], comp) | ||
| return | ||
| } | ||
|
|
||
| comp.dependencies = dependinces(container, rt, rv) | ||
|
|
||
| if len(comp.dependencies) != 0 && !ptr { | ||
| panic(incompletedError{}) | ||
| } | ||
|
|
@@ -173,6 +184,18 @@ func (container Container) Resolve(out interface{}, id ...string) { | |
| panic(notAddressableError{id: nam, paramType: rt, component: comp}) | ||
| } | ||
| } else { | ||
|
|
||
| if rt.Kind() == reflect.Interface { | ||
| for _, group := range container.components { | ||
| if v, e := group.find(nam); e { | ||
| if v.value.Addr().Type().Implements(rt) { | ||
| reflect.Indirect(rv).Set(v.value) | ||
| return | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if gr, ok := container.components[rt]; ok { | ||
| rv.Set(gr.get(nam).value) | ||
| return | ||
|
|
@@ -183,7 +206,37 @@ func (container Container) Resolve(out interface{}, id ...string) { | |
| } | ||
|
|
||
| // Apply wiring to all components. | ||
| func (container Container) Apply() { | ||
| func (container Container) Apply(to ...interface{}) { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. interesting, this allows components added directly in apply function right? |
||
|
|
||
| if len(to) > 0 { | ||
|
|
||
| rv := reflect.ValueOf(to[0]) | ||
| rt := rv.Type() | ||
| _, file, no, _ := runtime.Caller(container.callerSkip + 1) | ||
|
|
||
| comp := component{ | ||
| id: "", | ||
| value: rv, | ||
| declaredAt: file + ":" + strconv.Itoa(no), | ||
| } | ||
|
|
||
| if rt.Kind() == reflect.Ptr { | ||
| rt = rt.Elem() | ||
| rv = rv.Elem() | ||
| comp.value = rv | ||
| } | ||
|
|
||
| comp.dependencies = dependinces( | ||
| container, | ||
| rt, | ||
| rv, | ||
| ) | ||
|
|
||
| container.fill(comp) | ||
|
|
||
| return | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need to return here? this will cause other components that connected using |
||
| } | ||
|
|
||
| for _, gr := range container.components { | ||
| for _, comp := range gr { | ||
| container.fill(comp) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't this supposed to be
dependencies?https://www.collinsdictionary.com/dictionary/english/dependencies