项目地址
https://github.com/codegangsta/inject
依赖注入,就是将对象设置好,注入到容器中,使用等操作交给容器去处理,这个库其实就是核心就是一个非安全的基本类型map
type Injector interface { Applicator Invoker TypeMapper // SetParent sets the parent of the injector. If the injector cannot find a // dependency in its Type map it will check its parent before returning an // error. SetParent(Injector) }
// TypeMapper represents an interface for mapping interface{} values based on type. type TypeMapper interface { // Maps the interface{} value based on its immediate type from reflect.TypeOf. Map(interface{}) TypeMapper // Maps the interface{} value based on the pointer of an Interface provided. // This is really only useful for mapping a value as an interface, as interfaces // cannot at this time be referenced directly without a pointer. MapTo(interface{}, interface{}) TypeMapper // Provides a possibility to directly insert a mapping based on type and value. // This makes it possible to directly map type arguments not possible to instantiate // with reflect like unidirectional channels. Set(reflect.Type, reflect.Value) TypeMapper // Returns the Value that is mapped to the current type. Returns a zeroed Value if // the Type has not been mapped. Get(reflect.Type) reflect.Value }
type injector struct { values map[reflect.Type]reflect.Value parent Injector }
主要就是这三个地方了,po代码没太大意思也,如果想具体学习,叶大有一篇blog讲的很清晰。
https://www.cnblogs.com/yjf512/p/12121345.html
我也跟着做了个范例
package main import ( "fmt" "github.com/codegangsta/inject" "gopkg.in/macaron.v1" "reflect" ) type A struct { Name string } type B struct { Name string } type I interface { GetName() string } func (b *B) GetName() string { return b.Name } type C struct { Astruct A `inject` Bstruct B `inject` } type MyFastInvoker func(arg1 A, arg2 I, arg3 string) // 自己的invoke,这样就可以避免走反射了 func (invoker MyFastInvoker) Invoke(args []interface{}) ([]reflect.Value, error) { if a, ok := args[0].(A); ok { fmt.Println(a.Name) } if b, ok := args[1].(I); ok { fmt.Println(b.GetName()) } if c, ok := args[2].(string); ok { fmt.Println(c) } return nil, nil } func InjectDemo() { a := A{Name:"a name"} inject1 := inject.New() inject1.Map(a) inject1.MapTo(&B{Name:"b name"}, (*I)(nil)) inject1.Set(reflect.TypeOf("string"), reflect.ValueOf("c name")) inject1.Invoke(func(arg1 A, arg2 I, arg3 string) { fmt.Println(arg1.Name) fmt.Println(arg2.GetName()) fmt.Println(arg3) }) c := C{} inject1.Apply(&c) fmt.Println(c.Astruct.Name) inject2 := inject.New() inject2.Map(a) inject2.MapTo(&B{Name:"b name"}, (*I)(nil)) inject2.Set(reflect.TypeOf("string"), reflect.ValueOf("c name")) //inject2.Invoke(MyFastInvoker(nil)) } func main() { InjectDemo() a := &A{Name:"a name"} m := macaron.Classic() m.Map(a) m.Get("/", func(a *A) string { return "hello world " + a.Name }) m.Run() }
整体依赖反射
end