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 (
AnnotationTag = "annotation"
AnnotationMetaTag = "annotation-meta"
AnnotationMetaTag = "@annotation"
AnnotationChar = "@"
AnnotationStartChar = "("
AnnotationEndChar = ")"

View File

@ -13,17 +13,25 @@ func init() {
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 {
return fmt.Errorf("DI: name[%s] of annotation exist already", name)
}
meta := getMetaFields(t)
fRT, _, _ := cur.GetTypeInfo(t)
def := &AnnotationDefinition{
t: t,
rt: fRT,
rt: rt,
fields: meta,
}
@ -38,3 +46,21 @@ type AnnotationDefinition struct {
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"
)
const (
ComponentTag = "@Component"
)
var ComponentAnnotationType = reflect.TypeOf((*ComponentAnnotation)(nil))
func init() {
cda.RegisterAnnotation(ComponentTag, reflect.TypeOf((*Component)(nil)))
cda.RegisterAnnotation(ComponentAnnotationType)
}
type Component struct {
cda.Annotation
Name string `annotation-meta:"name"`
InitMethod string `annotation-meta:"initMethod"` // func (receiver interface{}, cr ComponentRegistry) error
DestroyMethod string `annotation-meta:"destroyMethod"` // func (receiver interface{}, cr ComponentRegistry) error
Scope di.ScopeType `annotation-meta:"scope"`
type ComponentAnnotation struct {
cda.TypeAnnotation `@annotation:"@Component"`
Name string `@annotation:"name"`
InitMethod string `@annotation:"initMethod"` // func (receiver interface{}, cr ComponentRegistry) error
DestroyMethod string `@annotation:"destroyMethod"` // func (receiver interface{}, cr ComponentRegistry) error
Scope di.ScopeType `@annotation:"scope"`
}

View File

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

View File

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

View File

@ -26,6 +26,7 @@ type ComponentRegistry interface {
GetInstances(ts []reflect.Type) ([]interface{}, error)
GetInstanceByName(name string) (interface{}, error)
GetInstancesByAnnotationName(n string) ([]interface{}, error)
GetInstancesByAnnotationType(t reflect.Type) ([]interface{}, error)
}
func newRegistry() ComponentRegistry {
@ -74,8 +75,8 @@ func (cr *defaultComponentRegistry) RegisterType(t reflect.Type) {
name := td.TypeName
if a := td.GetAnnotationByType(reflect.TypeOf((*cdia.Component)(nil)), true); nil != a {
ca := a.(*cdia.Component)
if a := td.GetAnnotationByType(cdia.ComponentAnnotationType, true); nil != a {
ca := a.(*cdia.ComponentAnnotation)
if "" != strings.Trim(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)
}
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 {
return nil, err
}
}
if annotation = fd.GetAnnotationByType(reflect.TypeOf((*cdia.Resource)(nil)), false); nil != annotation {
n := annotation.(*cdia.Resource).Name
if annotation = fd.GetAnnotationByType(cdia.ResourceAnnotationType, false); nil != annotation {
n := annotation.(*cdia.ResourceAnnotation).Name
if "" == n {
n = fd.FieldName
}
@ -236,6 +237,28 @@ func (cr *defaultComponentRegistry) GetInstancesByAnnotationName(n string) ([]in
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) {
if nil == t {
return nil, fmt.Errorf("t[reflect.Type] is nil")
@ -266,7 +289,7 @@ func parseFields(t reflect.Type, td *TypeDefinition) {
f := rt.Field(i)
if f.Anonymous {
parseAnonymousField(f, td)
parseAnonymousField(&f, td)
parseFields(f.Type, td)
} else {
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)
}
func parseTypeAnnotation(f reflect.StructField, td *TypeDefinition) {
func parseTypeAnnotation(f *reflect.StructField, td *TypeDefinition) {
if !haveEmbeddingOf(cda.TypeAnnotationType, f.Type) {
return
}

View File

@ -29,7 +29,7 @@ func TestRegisterType(t *testing.T) {
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", css)