This commit is contained in:
crusader 2018-04-07 01:57:25 +09:00
parent ee2ede6bd9
commit 52ae4371ce
7 changed files with 80 additions and 37 deletions

View File

@ -8,7 +8,7 @@ import (
const ( const (
AnnotationTag = "annotation" AnnotationTag = "annotation"
AnnotationMetaTag = "annotation-meta" AnnotationMetaTag = "@annotation"
AnnotationChar = "@" AnnotationChar = "@"
AnnotationStartChar = "(" AnnotationStartChar = "("
AnnotationEndChar = ")" AnnotationEndChar = ")"

View File

@ -13,17 +13,25 @@ func init() {
annotationRegistry = make(map[string]*AnnotationDefinition, 0) annotationRegistry = make(map[string]*AnnotationDefinition, 0)
} }
func RegisterAnnotation(name string, t reflect.Type) error { func RegisterAnnotation(t reflect.Type) error {
rt, _, _ := cur.GetTypeInfo(t)
f := getTypeAnnotationField(t)
if nil == f {
return fmt.Errorf("DI: This type[%s] is not Annotation", rt.Name())
}
name, _ := parseAnnotationMeta(f.Tag)
if _, ok := annotationRegistry[name]; ok { if _, ok := annotationRegistry[name]; ok {
return fmt.Errorf("DI: name[%s] of annotation exist already", name) return fmt.Errorf("DI: name[%s] of annotation exist already", name)
} }
meta := getMetaFields(t) meta := getMetaFields(t)
fRT, _, _ := cur.GetTypeInfo(t)
def := &AnnotationDefinition{ def := &AnnotationDefinition{
t: t, t: t,
rt: fRT, rt: rt,
fields: meta, fields: meta,
} }
@ -38,3 +46,21 @@ type AnnotationDefinition struct {
fields map[string]*AnnotationFieldMeta fields map[string]*AnnotationFieldMeta
} }
func getTypeAnnotationField(t reflect.Type) *reflect.StructField {
rt, _, _ := cur.GetTypeInfo(t)
if reflect.Struct != rt.Kind() {
return nil
}
for i := 0; i < rt.NumField(); i++ {
f := rt.Field(i)
if f.Anonymous {
if f.Type == TypeAnnotationType {
return &f
}
}
}
return nil
}

View File

@ -9,18 +9,16 @@ import (
cda "git.loafle.net/commons/di-go/annotation" cda "git.loafle.net/commons/di-go/annotation"
) )
const ( var ComponentAnnotationType = reflect.TypeOf((*ComponentAnnotation)(nil))
ComponentTag = "@Component"
)
func init() { func init() {
cda.RegisterAnnotation(ComponentTag, reflect.TypeOf((*Component)(nil))) cda.RegisterAnnotation(ComponentAnnotationType)
} }
type Component struct { type ComponentAnnotation struct {
cda.Annotation cda.TypeAnnotation `@annotation:"@Component"`
Name string `annotation-meta:"name"` Name string `@annotation:"name"`
InitMethod string `annotation-meta:"initMethod"` // func (receiver interface{}, cr ComponentRegistry) error InitMethod string `@annotation:"initMethod"` // func (receiver interface{}, cr ComponentRegistry) error
DestroyMethod string `annotation-meta:"destroyMethod"` // func (receiver interface{}, cr ComponentRegistry) error DestroyMethod string `@annotation:"destroyMethod"` // func (receiver interface{}, cr ComponentRegistry) error
Scope di.ScopeType `annotation-meta:"scope"` Scope di.ScopeType `@annotation:"scope"`
} }

View File

@ -8,15 +8,13 @@ import (
cda "git.loafle.net/commons/di-go/annotation" cda "git.loafle.net/commons/di-go/annotation"
) )
const ( var InjectAnnotationType = reflect.TypeOf((*InjectAnnotation)(nil))
InjectTag = "@Inject"
)
func init() { func init() {
cda.RegisterAnnotation(InjectTag, reflect.TypeOf((*Inject)(nil))) cda.RegisterAnnotation(InjectAnnotationType)
} }
type Inject struct { type InjectAnnotation struct {
cda.Annotation cda.TypeAnnotation `@annotation:"@Inject"`
Name string `annotation-meta:"name"` Name string `@annotation:"name"`
} }

View File

@ -6,15 +6,13 @@ import (
cda "git.loafle.net/commons/di-go/annotation" cda "git.loafle.net/commons/di-go/annotation"
) )
const ( var ResourceAnnotationType = reflect.TypeOf((*ResourceAnnotation)(nil))
ResourceTag = "@Resource"
)
func init() { func init() {
cda.RegisterAnnotation(ResourceTag, reflect.TypeOf((*Resource)(nil))) cda.RegisterAnnotation(ResourceAnnotationType)
} }
type Resource struct { type ResourceAnnotation struct {
cda.Annotation cda.TypeAnnotation `@annotation:"@Resource"`
Name string `annotation-meta:"name"` Name string `@annotation:"name"`
} }

View File

@ -26,6 +26,7 @@ type ComponentRegistry interface {
GetInstances(ts []reflect.Type) ([]interface{}, error) GetInstances(ts []reflect.Type) ([]interface{}, error)
GetInstanceByName(name string) (interface{}, error) GetInstanceByName(name string) (interface{}, error)
GetInstancesByAnnotationName(n string) ([]interface{}, error) GetInstancesByAnnotationName(n string) ([]interface{}, error)
GetInstancesByAnnotationType(t reflect.Type) ([]interface{}, error)
} }
func newRegistry() ComponentRegistry { func newRegistry() ComponentRegistry {
@ -74,8 +75,8 @@ func (cr *defaultComponentRegistry) RegisterType(t reflect.Type) {
name := td.TypeName name := td.TypeName
if a := td.GetAnnotationByType(reflect.TypeOf((*cdia.Component)(nil)), true); nil != a { if a := td.GetAnnotationByType(cdia.ComponentAnnotationType, true); nil != a {
ca := a.(*cdia.Component) ca := a.(*cdia.ComponentAnnotation)
if "" != strings.Trim(ca.Name, " ") { if "" != strings.Trim(ca.Name, " ") {
name = ca.Name name = ca.Name
} }
@ -153,14 +154,14 @@ func (cr *defaultComponentRegistry) GetInstance(t reflect.Type) (interface{}, er
return nil, fmt.Errorf("DI: Field[%s] can not set", fd.FieldName) return nil, fmt.Errorf("DI: Field[%s] can not set", fd.FieldName)
} }
if annotation = fd.GetAnnotationByType(reflect.TypeOf((*cdia.Inject)(nil)), false); nil != annotation { if annotation = fd.GetAnnotationByType(cdia.InjectAnnotationType, false); nil != annotation {
if fV, err = cr.GetInstance(fd.Type); nil != err { if fV, err = cr.GetInstance(fd.Type); nil != err {
return nil, err return nil, err
} }
} }
if annotation = fd.GetAnnotationByType(reflect.TypeOf((*cdia.Resource)(nil)), false); nil != annotation { if annotation = fd.GetAnnotationByType(cdia.ResourceAnnotationType, false); nil != annotation {
n := annotation.(*cdia.Resource).Name n := annotation.(*cdia.ResourceAnnotation).Name
if "" == n { if "" == n {
n = fd.FieldName n = fd.FieldName
} }
@ -236,6 +237,28 @@ func (cr *defaultComponentRegistry) GetInstancesByAnnotationName(n string) ([]in
return instances, nil return instances, nil
} }
func GetInstancesByAnnotationType(t reflect.Type) ([]interface{}, error) {
return registry.GetInstancesByAnnotationType(t)
}
func (cr *defaultComponentRegistry) GetInstancesByAnnotationType(t reflect.Type) ([]interface{}, error) {
var (
i interface{}
err error
)
instances := make([]interface{}, 0)
for _, td := range cr.definitionByType {
if nil != td.GetAnnotationByType(t, true) {
if i, err = cr.GetInstance(td.Type); nil != err {
return nil, err
}
instances = append(instances, i)
}
}
return instances, nil
}
func (cr *defaultComponentRegistry) buildDefinition(t reflect.Type) (*TypeDefinition, error) { func (cr *defaultComponentRegistry) buildDefinition(t reflect.Type) (*TypeDefinition, error) {
if nil == t { if nil == t {
return nil, fmt.Errorf("t[reflect.Type] is nil") return nil, fmt.Errorf("t[reflect.Type] is nil")
@ -266,7 +289,7 @@ func parseFields(t reflect.Type, td *TypeDefinition) {
f := rt.Field(i) f := rt.Field(i)
if f.Anonymous { if f.Anonymous {
parseAnonymousField(f, td) parseAnonymousField(&f, td)
parseFields(f.Type, td) parseFields(f.Type, td)
} else { } else {
as, err := cda.ParseAnnotation(f.Tag) as, err := cda.ParseAnnotation(f.Tag)
@ -290,11 +313,11 @@ func parseFields(t reflect.Type, td *TypeDefinition) {
} }
} }
func parseAnonymousField(f reflect.StructField, td *TypeDefinition) { func parseAnonymousField(f *reflect.StructField, td *TypeDefinition) {
parseTypeAnnotation(f, td) parseTypeAnnotation(f, td)
} }
func parseTypeAnnotation(f reflect.StructField, td *TypeDefinition) { func parseTypeAnnotation(f *reflect.StructField, td *TypeDefinition) {
if !haveEmbeddingOf(cda.TypeAnnotationType, f.Type) { if !haveEmbeddingOf(cda.TypeAnnotationType, f.Type) {
return return
} }

View File

@ -29,7 +29,7 @@ func TestRegisterType(t *testing.T) {
RegisterResource("List", []string{"dfdkf", "skgkfg"}) RegisterResource("List", []string{"dfdkf", "skgkfg"})
if css, err = GetInstancesByAnnotationName(cdia.ComponentTag); nil != err { if css, err = GetInstancesByAnnotationType(cdia.ComponentAnnotationType); nil != err {
log.Printf("%v \n", err) log.Printf("%v \n", err)
} }
log.Printf("%v", css) log.Printf("%v", css)