diff options
author | Wolfy-J <[email protected]> | 2018-07-26 16:32:27 +0300 |
---|---|---|
committer | Wolfy-J <[email protected]> | 2018-07-26 16:32:27 +0300 |
commit | bcef5b36bb50b2fecd4db4ca8e01640347300bea (patch) | |
tree | b6db6954063dd3288a80f24aa714e8799664d909 /service/container.go | |
parent | 0f8e2bab6888f1b27ed2bd1b91ac6b2677f03450 (diff) |
- added support for custom env provider
- new config section "env" to share env variables with php process
- container can resolve interfaces now
Diffstat (limited to 'service/container.go')
-rw-r--r-- | service/container.go | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/service/container.go b/service/container.go index 436d2e5f..3450a18c 100644 --- a/service/container.go +++ b/service/container.go @@ -8,7 +8,7 @@ import ( "sync" ) -var noConfig = fmt.Errorf("no config has been provided") +var errNoConfig = fmt.Errorf("no config has been provided") // InitMethod contains name of the method to be automatically invoked while service initialization. Must return // (bool, error). Container can be requested as well. Config can be requested in a form @@ -132,7 +132,7 @@ func (c *container) Init(cfg Config) error { // inject service dependencies if ok, err := c.initService(e.svc, cfg.Get(e.name)); err != nil { // soft error (skipping) - if err == noConfig { + if err == errNoConfig { c.log.Warningf("[%s]: no config has been provided", e.name) continue } @@ -253,7 +253,7 @@ func (c *container) resolveValues(s interface{}, m reflect.Method, cfg Config) ( case v.Implements(reflect.TypeOf((*HydrateConfig)(nil)).Elem()): // injectable config if cfg == nil { - return nil, noConfig + return nil, errNoConfig } sc := reflect.New(v.Elem()) @@ -265,27 +265,18 @@ func (c *container) resolveValues(s interface{}, m reflect.Method, cfg Config) ( case v.Implements(reflect.TypeOf((*Config)(nil)).Elem()): // generic config section if cfg == nil { - return nil, noConfig + return nil, errNoConfig } values = append(values, reflect.ValueOf(cfg)) default: // dependency on other service (resolution to nil if service can't be found) - found := false - for _, e := range c.services { - if !e.hasStatus(StatusOK) || !v.ConvertibleTo(reflect.ValueOf(e.svc).Type()) { - continue - } - - found = true - values = append(values, reflect.ValueOf(e.svc)) - break + value, err := c.resolveValue(v) + if err != nil { + return nil, err } - if !found { - // placeholder (make sure to check inside the method) - values = append(values, reflect.New(v).Elem()) - } + values = append(values, value) } } @@ -308,3 +299,35 @@ func (c *container) verifySignature(m reflect.Method) error { return nil } + +func (c *container) resolveValue(v reflect.Type) (reflect.Value, error) { + value := reflect.Value{} + for _, e := range c.services { + if !e.hasStatus(StatusOK) { + continue + } + + if v.Kind() == reflect.Interface && reflect.TypeOf(e.svc).Implements(v) { + if value.IsValid() { + return value, fmt.Errorf("disambiguous dependency `%s`", v) + } + + value = reflect.ValueOf(e.svc) + } + + if v.ConvertibleTo(reflect.ValueOf(e.svc).Type()) { + if value.IsValid() { + return value, fmt.Errorf("disambiguous dependency `%s`", v) + } + + value = reflect.ValueOf(e.svc) + } + } + + if !value.IsValid() { + // placeholder (make sure to check inside the method) + value = reflect.New(v).Elem() + } + + return value, nil +} |