ing
This commit is contained in:
parent
dc841686a6
commit
274c05cbf0
|
@ -1,6 +1,12 @@
|
||||||
package annotation
|
package annotation
|
||||||
|
|
||||||
type Component struct {
|
import (
|
||||||
Names *[]string
|
"git.loafle.net/commons_go/di"
|
||||||
Scope *ScopeType
|
)
|
||||||
|
|
||||||
|
type ComponentAnnotation struct {
|
||||||
|
Names []string
|
||||||
|
InitMethod string // func (receiver interface{}, cr ComponentRegistry) error
|
||||||
|
DestroyMethod string // func (receiver interface{}, cr ComponentRegistry) error
|
||||||
|
Scope di.ScopeType
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package annotation
|
package annotation
|
||||||
|
|
||||||
type Inject struct {
|
type Inject struct {
|
||||||
Name *string
|
Name string
|
||||||
Required *bool
|
|
||||||
}
|
}
|
||||||
|
|
5
annotation/resource.go
Normal file
5
annotation/resource.go
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
package annotation
|
||||||
|
|
||||||
|
type Resource struct {
|
||||||
|
Name string
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
package annotation
|
|
||||||
|
|
||||||
type ScopeType int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ScopeTypeSingleton ScopeType = iota
|
|
||||||
ScopeTypeTransiant
|
|
||||||
)
|
|
25
constants.go
Normal file
25
constants.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package di
|
||||||
|
|
||||||
|
// `annotation:"@Inject(name? string)"`
|
||||||
|
// field 에 적용
|
||||||
|
// 1. 타입으로 매칭 없으면 에러 2. 여러개의 타입이 검색되면 그 중에 name으로 매칭
|
||||||
|
|
||||||
|
// `annotation:"@Resource(name? string)"`
|
||||||
|
// field 에 적용
|
||||||
|
// 1. 이름으로 매칭 2. 타입으로 매칭
|
||||||
|
// 이름이 지정되지 않으면 field 이름으로 먼저 찾고 없으면 타입으로 매칭
|
||||||
|
|
||||||
|
// @Component
|
||||||
|
// Component 등록 시에 파라미터로 제공
|
||||||
|
// names []string
|
||||||
|
// initMethod string
|
||||||
|
// destroyMethod string
|
||||||
|
// scope enum singleton, transiant
|
||||||
|
|
||||||
|
type ScopeType int
|
||||||
|
|
||||||
|
const (
|
||||||
|
ScopeTypeDefault ScopeType = iota // == ScopeTypeSingleton
|
||||||
|
ScopeTypeSingleton
|
||||||
|
ScopeTypeTransiant
|
||||||
|
)
|
112
ex
112
ex
|
@ -1,112 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
|
@ -2,27 +2,9 @@ package registry
|
||||||
|
|
||||||
import "reflect"
|
import "reflect"
|
||||||
|
|
||||||
type typeDefinition struct {
|
type ComponentDefinition struct {
|
||||||
pkgName string
|
PkgName string
|
||||||
typeName string
|
TypeName string
|
||||||
targetType reflect.Type
|
Type reflect.Type
|
||||||
realType reflect.Type
|
RealType reflect.Type
|
||||||
|
|
||||||
fields map[string]
|
|
||||||
}
|
|
||||||
|
|
||||||
type fieldDefinition struct {
|
|
||||||
pkgName string
|
|
||||||
typeName string
|
|
||||||
targetType reflect.Type
|
|
||||||
realType reflect.Type
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type Service struct {
|
|
||||||
DAO *DAO `di-annotation:""`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DAO struct {
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -4,22 +4,25 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
cda "git.loafle.net/commons_go/di/annotation"
|
||||||
cdur "git.loafle.net/commons_go/di/util/reflect"
|
cdur "git.loafle.net/commons_go/di/util/reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ComponentRegistry interface {
|
type ComponentRegistry interface {
|
||||||
RegisterType(t reflect.Type, name string) error
|
RegisterType(t reflect.Type, ca *cda.ComponentAnnotation) error
|
||||||
RegisterFactory(i interface{}) error
|
RegisterFactory(i interface{}, ca *cda.ComponentAnnotation) error
|
||||||
|
|
||||||
GetInstance(t reflect.Type) (interface{}, error)
|
GetInstance(t reflect.Type) (interface{}, error)
|
||||||
GetInstanceByName(name string) (interface{}, error)
|
GetInstanceByName(name string) (interface{}, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type defaultComponentRegistry struct {
|
type defaultComponentRegistry struct {
|
||||||
definitions map[string]reflect.Type
|
definitionsByType map[reflect.Type]*ComponentDefinition
|
||||||
|
|
||||||
|
definitionByName map[string]*ComponentDefinition
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *defaultComponentRegistry) RegisterType(t reflect.Type, name string) error {
|
func (cr *defaultComponentRegistry) RegisterType(t reflect.Type, ca *cda.ComponentAnnotation) error {
|
||||||
if nil == t {
|
if nil == t {
|
||||||
return fmt.Errorf("DI: t[reflect.Type] is nil")
|
return fmt.Errorf("DI: t[reflect.Type] is nil")
|
||||||
}
|
}
|
||||||
|
@ -27,18 +30,21 @@ func (cr *defaultComponentRegistry) RegisterType(t reflect.Type, name string) er
|
||||||
return fmt.Errorf("DI: t[reflect.Type] must be specified but is %v", t)
|
return fmt.Errorf("DI: t[reflect.Type] must be specified but is %v", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
rt, pkgName, tName := cdur.GetTypeName(t, true)
|
rt, pkgName, tName := cdur.GetTypeName(t)
|
||||||
cr.definitions[name] = rt
|
cr.definitions[name] = rt
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cr *defaultComponentRegistry) RegisterFactory(i interface{}) error {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cr *defaultComponentRegistry) GetInstance(t reflect.Type) (interface{}, error) {
|
func (cr *defaultComponentRegistry) GetInstance(t reflect.Type) (interface{}, error) {
|
||||||
|
if nil == t {
|
||||||
|
return nil, fmt.Errorf("DI: t[reflect.Type] is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
cd, ok := cr.definitionsByType[t]
|
||||||
|
if !ok {
|
||||||
|
cd = cr.buildDefinition(t)
|
||||||
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -47,3 +53,18 @@ func (cr *defaultComponentRegistry) GetInstanceByName(name string) (interface{},
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cr *defaultComponentRegistry) buildDefinition(t reflect.Type) (*ComponentDefinition, error) {
|
||||||
|
if nil == t {
|
||||||
|
return nil, fmt.Errorf("DI: t[reflect.Type] is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
rt, pkgName, tName := cdur.GetTypeName(t)
|
||||||
|
cd := &ComponentDefinition{}
|
||||||
|
cd.PkgName = pkgName
|
||||||
|
cd.TypeName = tName
|
||||||
|
cd.Type = t
|
||||||
|
cd.RealType = rt
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user