Skip to content

Commit 2550ded

Browse files
committed
init di
1 parent 08cfef0 commit 2550ded

6 files changed

Lines changed: 172 additions & 0 deletions

File tree

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.svn
2+
.tmp
3+
.download
4+
output
5+
.*.swp
6+
.*.swo
7+
log
8+
go.sum

README.md

Whitespace-only changes.

_example/di/go.mod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module github.com/AImager/wool/_example/di
2+
3+
go 1.13
4+
5+
replace github.com/AImager/wool => /Users/yucong04/Code/github.com/AImager/wool
6+
7+
require github.com/AImager/wool v0.0.0-00010101000000-000000000000

_example/di/main.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/AImager/wool"
6+
)
7+
8+
type AI interface {
9+
testA()
10+
}
11+
12+
type A1 struct{}
13+
14+
type A2 struct{}
15+
16+
func (a1 *A1) testA() {
17+
fmt.Println("a1")
18+
}
19+
20+
func (a2 *A2) testA() {
21+
fmt.Println("a2")
22+
}
23+
24+
func main() {
25+
// bind interface with factory method
26+
aFunc := func(name string) AI {
27+
switch name {
28+
case "A1":
29+
return &A1{}
30+
case "A2":
31+
return &A2{}
32+
default:
33+
return *new(AI)
34+
}
35+
}
36+
_ = wool.DI().Bind(new(AI), aFunc)
37+
38+
var ai = (AI)(nil)
39+
_ = wool.DI().Make(&ai, "A2")
40+
41+
ai.testA()
42+
43+
// bind interface with factory
44+
// golang can't find implement struct now
45+
//_ = di.DI().Bind(new(AI), A1{})
46+
//
47+
//ai1 := *new(AI)
48+
//_ = di.DI().Make(&ai1)
49+
}

di.go

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package wool
2+
3+
import (
4+
"errors"
5+
"reflect"
6+
)
7+
8+
// not export , so others can't implement the package
9+
type dic struct {
10+
container map[reflect.Type]*__obj
11+
}
12+
13+
type DIC interface {
14+
Bind(it interface{}, v interface{}) error
15+
BindSingleton(it interface{}, v interface{}) error
16+
Make(it interface{}, args ...interface{}) error
17+
}
18+
19+
var di *dic
20+
21+
type __obj struct {
22+
instance interface{}
23+
__type reflect.Type
24+
__value reflect.Value
25+
singleton bool
26+
}
27+
28+
// DI singleton
29+
func DI() DIC {
30+
if di == nil {
31+
di = &dic{
32+
container: make(map[reflect.Type]*__obj),
33+
}
34+
}
35+
return di
36+
}
37+
38+
func (di *dic) Bind(it interface{}, v interface{}) error {
39+
return di.bind(it, v, false)
40+
}
41+
42+
func (di *dic) BindSingleton(it interface{}, v interface{}) error {
43+
return di.bind(it, v, true)
44+
}
45+
46+
// Bind it's type must be no-empty reflect.Interface
47+
// c's type can be reflect.Func or reflect.Struct
48+
func (di *dic) bind(it interface{}, v interface{}, singleton bool) error {
49+
itType := reflect.TypeOf(it)
50+
vType := reflect.TypeOf(v)
51+
if itType.Kind() != reflect.Ptr {
52+
return errors.New("it is not ptr")
53+
}
54+
// just check
55+
switch vType.Kind() {
56+
case reflect.Func:
57+
if vType.In(0) != reflect.TypeOf(di) {
58+
return errors.New("first params must be DIC")
59+
}
60+
if vType.Out(0) != itType {
61+
return errors.New("first return params must same as it's type")
62+
}
63+
default:
64+
}
65+
obj := &__obj{
66+
__type: vType,
67+
__value: reflect.ValueOf(v),
68+
}
69+
di.set(itType, obj)
70+
return nil
71+
}
72+
73+
// Make it must be reflect.Ptr
74+
// it's point obj must be reflect.Struct or reflect.Interface
75+
func (di *dic) Make(it interface{}, args ...interface{}) error {
76+
itType := reflect.TypeOf(it)
77+
obj, ok := di.load(itType)
78+
if itType.Kind() != reflect.Ptr || !ok {
79+
return errors.New("can't find interface")
80+
}
81+
switch obj.__type.Kind() {
82+
case reflect.Func:
83+
var argValues = make([]reflect.Value, 0)
84+
for _, arg := range args {
85+
argValues = append(argValues, reflect.ValueOf(arg))
86+
}
87+
// todo error handle
88+
buildValue := obj.__value.Call(argValues)
89+
reflect.ValueOf(it).Elem().Set(buildValue[0])
90+
default:
91+
reflect.ValueOf(it).Elem().Set(obj.__value)
92+
return nil
93+
}
94+
return nil
95+
}
96+
97+
// todo lock
98+
func (di *dic) set(it reflect.Type, c *__obj) {
99+
di.container[it] = c
100+
}
101+
102+
func (di *dic) load(it reflect.Type) (obj *__obj, exist bool) {
103+
obj, exist = di.container[it]
104+
return
105+
}

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module github.com/AImager/wool
2+
3+
go 1.13

0 commit comments

Comments
 (0)