package main import ( "errors" "fmt" "log" "reflect" "git.loafle.net/prototype/reflection/service" ) func main() { var err error r := &Registry{} // if err = r.RegisterType(&Dao{}); nil != err { // log.Printf("%v \n", err) // } if err = r.RegisterType(reflect.TypeOf((*service.MemberService)(nil))); nil != err { log.Printf("%v \n", err) } // if err = r.RegisterType(&prsu.UserService{}); nil != err { // log.Printf("%v \n", err) // } // if err = r.RegisterType(prsu.UserService{}); nil != err { // log.Printf("%v \n", err) // } // if err = r.RegisterFactory(NewService); nil != err { // log.Printf("%v \n", err) // } // if err = r.RegisterType(&Controller{}); nil != err { // log.Printf("%v \n", err) // } } func NewService() *Service { return &Service{} } type Registry struct { } func (r *Registry) RegisterType(t reflect.Type) error { // t := reflect.TypeOf(s) if nil == t { return errors.New("can't provide an untyped nil") } if !IsType(t, reflect.Struct) { return fmt.Errorf("must provide struct, got %v", t) } name, rt := GetTypeName(t) log.Printf("The name of Type: %s", name) fN := rt.NumField() for i := 0; i < fN; i++ { f := rt.Field(i) log.Printf("The PkgPath: %s", f.PkgPath) log.Printf("The field[%s] of [%s] is pointer :%v", f.Name, name, f.Type.Kind() == reflect.Ptr) log.Printf("The tag of [%s.%s]: %s", name, f.Name, f.Tag.Get("annotation")) } return nil } // func (r *Registry) RegisterFactory(s interface{}) error { // t := reflect.TypeOf(s) // if nil == t { // return errors.New("can't provide an untyped nil") // } // if !IsType(t, reflect.Func) { // return fmt.Errorf("must provide constructor function, got %v (type %v)", s, t) // } // log.Printf("The name of Type: %s", GetTypeName(t)) // log.Printf("The name of Type: %v", t.IsVariadic()) // log.Printf("The name of Type: %s", t.PkgPath()) // log.Printf("The name of Type: %s", GetTypeName(t.Out(0))) // return nil // } type Controller struct { service *Service `annotation:"transiant:singleton"` MemberService *service.MemberService `annotation:"transiant:singleton"` } type Service struct { Dao *Dao `annotation:"transiant:singleton"` } type Dao struct { } func IsType(t reflect.Type, kind reflect.Kind) bool { if reflect.Ptr == t.Kind() { return IsType(t.Elem(), kind) } return kind == t.Kind() } func GetTypeName(t reflect.Type) (string, reflect.Type) { if reflect.Ptr == t.Kind() { return GetTypeName(t.Elem()) } return fmt.Sprintf("%s/%s", t.PkgPath(), t.Name()), t }