codegangsta/inject

Hide reflect.Value/Type from interfaces

Opened this issue · 1 comments

When using Invoke() or Get() you have to do a lot of Interface() and type assertions. It may be useful to change some of the methods to use plain interfaces{}, similar to how encoding/json works.

I was thinking Get would look something like this:

func (i *injector) Get(dst interface{}) {
    dval := reflect.ValueOf(dst).Elem()
    val := i.values[dval.Type()]
    if val.IsValid() {
        dval.Set(val)
    } else if i.parent != nil {
        i.parent.Get(dst)
    }
}

func (i *injector) GetInterface(dst interface{}, ifacePtr interface{}) {
    val := i.values[InterfaceOf(ifacePtr)]
    if val.IsValid() {
        reflect.ValueOf(dst).Elem().Set(val)
    } else if i.parent != nil {
        i.parent.GetInterface(dst, ifacePtr)
    }
}

These functions would be used like this:

obj := Obj{}

i.Get(&obj)
// OR
i.GetInterface(&obj, (*MyInterface)(nil))

Verses this:

ov := i.Get(Obj{})
// OR
ov := i.Get(InterfaceOf((*MyInterface)(nil)))

obj = ov.Interface().(Obj)

You could probably optimize this further by doing reflect.ValueOf/TypeOf once in the public methods and pass those to private methods that understand reflect.Value/Type.

Invoke could return []interface{} instead of []reflect.Value.

Yup. I agree with this that we can optimize the API to be cleaner for Getting values out of the type map