Skip to content

Commit 40f9d14

Browse files
author
yoyofx
committed
init
0 parents  commit 40f9d14

10 files changed

+255
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.idea
2+
*.sum

default_serviceprovider.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package dependencyinjection
2+
3+
import (
4+
"github.com/goava/di"
5+
"unsafe"
6+
)
7+
8+
type DefaultServiceProvider struct {
9+
container *di.Container
10+
}
11+
12+
func (d DefaultServiceProvider) GetService(refObject interface{}) (err error) {
13+
err = d.container.Resolve(refObject)
14+
return err
15+
}
16+
17+
func (d DefaultServiceProvider) GetServiceByName(refObject interface{}, name string) (err error) {
18+
err = d.container.Resolve(refObject, di.Name(name))
19+
return err
20+
}
21+
22+
func (d DefaultServiceProvider) GetServiceByTags(refObject interface{}, tags map[string]string) (err error) {
23+
p := unsafe.Pointer(&tags)
24+
var tag di.Tags
25+
tag = *(*di.Tags)(p)
26+
err = d.container.Resolve(refObject, tag)
27+
return err
28+
}
29+
30+
func (d DefaultServiceProvider) GetGraph() string {
31+
return ""
32+
}
33+
34+
func (d DefaultServiceProvider) InvokeService(fn interface{}) error {
35+
return d.container.Invoke(fn)
36+
}

default_serviceprovider_factory.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package dependencyinjection
2+
3+
import (
4+
"github.com/goava/di"
5+
)
6+
7+
func (sc ServiceCollection) Build() IServiceProvider {
8+
var providers []di.Option
9+
for _, desc := range sc.serviceDescriptors {
10+
11+
var providerOptions []di.ProvideOption
12+
if desc.Implements != nil {
13+
providerOptions = append(providerOptions, di.As(desc.Implements))
14+
}
15+
if desc.Name != "" {
16+
providerOptions = append(providerOptions, di.WithName(desc.Name))
17+
}
18+
//prototype is create a new instance on each call.
19+
if desc.Lifetime != Singleton {
20+
//providerOptions = append(providerOptions)
21+
}
22+
23+
provider := di.Provide(desc.Provider, providerOptions...)
24+
providers = append(providers, provider)
25+
26+
}
27+
container, _ := di.New(providers...)
28+
29+
return &DefaultServiceProvider{container}
30+
}

di_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package dependencyinjection
2+
3+
import (
4+
"github.com/goava/di"
5+
"github.com/magiconair/properties/assert"
6+
"math/rand"
7+
"strconv"
8+
"testing"
9+
"time"
10+
"unsafe"
11+
)
12+
13+
type A struct {
14+
Name string
15+
}
16+
17+
var ls string
18+
19+
func NewA() *A {
20+
r := rand.New(rand.NewSource(time.Now().UnixNano()))
21+
ls = "A-" + strconv.Itoa(r.Int())
22+
return &A{Name: ls}
23+
}
24+
25+
func Test_DI_Register(t *testing.T) {
26+
services := NewServiceCollection()
27+
28+
services.AddSingleton(NewA)
29+
30+
serviceProvider := services.Build()
31+
32+
var env *A
33+
_ = serviceProvider.GetService(&env)
34+
assert.Equal(t, env.Name, ls)
35+
36+
_ = serviceProvider.GetService(&env)
37+
assert.Equal(t, env.Name, ls)
38+
39+
_ = serviceProvider.GetService(&env)
40+
assert.Equal(t, env.Name, ls)
41+
}
42+
43+
func Test_MapConvertTags(t *testing.T) {
44+
tags := map[string]string{"name": "A1"}
45+
p := unsafe.Pointer(&tags)
46+
var tag di.Tags
47+
tag = *(*di.Tags)(p)
48+
assert.Equal(t, tag != nil, true)
49+
}

go.mod

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/yoyofxteam/dependencyinjection
2+
3+
go 1.16
4+
5+
require (
6+
github.com/davecgh/go-spew v1.1.1 // indirect
7+
github.com/goava/di v1.10.0
8+
github.com/magiconair/properties v1.8.5
9+
github.com/yoyofxteam/reflectx v0.2.3
10+
)

servicecollection.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package dependencyinjection
2+
3+
import (
4+
"github.com/yoyofxteam/reflectx"
5+
"strings"
6+
)
7+
8+
type ServiceCollection struct {
9+
serviceDescriptors []*ServiceDescriptor
10+
serviceDescriptorMaps map[string]int
11+
}
12+
13+
func NewServiceCollection() *ServiceCollection {
14+
return &ServiceCollection{serviceDescriptorMaps: make(map[string]int)}
15+
}
16+
17+
//Singleton
18+
//Scoped
19+
//Transient
20+
func (sc *ServiceCollection) AddServiceDescriptor(sd *ServiceDescriptor) {
21+
typeName := sd.Name
22+
if typeName == "" {
23+
typeName, _ = reflectx.GetCtorFuncOutTypeName(sd.Provider)
24+
typeName = strings.ToLower(typeName)
25+
}
26+
27+
index := len(sc.serviceDescriptors)
28+
defIndex, exist := sc.serviceDescriptorMaps[typeName]
29+
if exist {
30+
sc.serviceDescriptors[defIndex] = sd
31+
} else {
32+
sc.serviceDescriptorMaps[typeName] = index
33+
sc.serviceDescriptors = append(sc.serviceDescriptors, sd)
34+
}
35+
}
36+
37+
func (sc *ServiceCollection) AddSingleton(provider interface{}) {
38+
sd := NewServiceDescriptorByProvider(provider, Singleton)
39+
sc.AddServiceDescriptor(sd)
40+
}
41+
42+
func (sc *ServiceCollection) AddSingletonAndName(name string, provider interface{}) {
43+
sc.AddSingletonByName(name, provider)
44+
sc.AddSingleton(provider)
45+
}
46+
47+
func (sc *ServiceCollection) AddSingletonByName(name string, provider interface{}) {
48+
sd := NewServiceDescriptorByName(name, provider, Singleton)
49+
sc.AddServiceDescriptor(sd)
50+
}
51+
52+
func (sc *ServiceCollection) AddSingletonByImplementsAndName(name string, provider interface{}, implements interface{}) {
53+
sc.AddSingletonByName(name, provider)
54+
sc.AddSingletonByImplements(provider, implements)
55+
}
56+
57+
func (sc *ServiceCollection) AddSingletonByImplements(provider interface{}, implements interface{}) {
58+
sd := NewServiceDescriptorByImplements(provider, implements, Singleton)
59+
sc.AddServiceDescriptor(sd)
60+
}
61+
62+
func (sc *ServiceCollection) AddSingletonByNameAndImplements(name string, provider interface{}, implements interface{}) {
63+
sd := NewServiceDescriptorByImplements(provider, implements, Singleton)
64+
sd.Name = name
65+
sc.AddServiceDescriptor(sd)
66+
}
67+
68+
func (sc *ServiceCollection) AddTransient(provider interface{}) {
69+
sd := NewServiceDescriptorByProvider(provider, Transient)
70+
sc.AddServiceDescriptor(sd)
71+
}
72+
73+
func (sc *ServiceCollection) AddTransientByName(name string, provider interface{}) {
74+
sd := NewServiceDescriptorByName(name, provider, Transient)
75+
sc.AddServiceDescriptor(sd)
76+
}
77+
78+
func (sc *ServiceCollection) AddTransientByImplements(provider interface{}, implements interface{}) {
79+
sd := NewServiceDescriptorByImplements(provider, implements, Transient)
80+
sc.AddServiceDescriptor(sd)
81+
}

servicedescriptor.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package dependencyinjection
2+
3+
type ServiceDescriptor struct {
4+
Name string
5+
Provider interface{}
6+
Implements interface{}
7+
Lifetime ServiceLifetime
8+
}
9+
10+
func NewServiceDescriptor(name string, provider interface{}, implements interface{}, lifetime ServiceLifetime) *ServiceDescriptor {
11+
return &ServiceDescriptor{Name: name, Provider: provider, Implements: implements, Lifetime: lifetime}
12+
}
13+
14+
func NewServiceDescriptorByProvider(provider interface{}, lifetime ServiceLifetime) *ServiceDescriptor {
15+
return &ServiceDescriptor{Provider: provider, Lifetime: lifetime}
16+
}
17+
18+
func NewServiceDescriptorByName(name string, provider interface{}, lifetime ServiceLifetime) *ServiceDescriptor {
19+
return &ServiceDescriptor{Name: name, Provider: provider, Lifetime: lifetime}
20+
}
21+
22+
func NewServiceDescriptorByImplements(provider interface{}, implements interface{}, lifetime ServiceLifetime) *ServiceDescriptor {
23+
return &ServiceDescriptor{Provider: provider, Implements: implements, Lifetime: lifetime}
24+
}

servicelifetime.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package dependencyinjection
2+
3+
type ServiceLifetime int32
4+
5+
const (
6+
Singleton ServiceLifetime = 0
7+
Scoped ServiceLifetime = 1
8+
Transient ServiceLifetime = 2
9+
)

serviceprovider.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package dependencyinjection
2+
3+
type IServiceProvider interface {
4+
GetService(refObject interface{}) error
5+
GetServiceByName(refObject interface{}, name string) error
6+
GetServiceByTags(refObject interface{}, tags map[string]string) (err error)
7+
GetGraph() string
8+
InvokeService(fn interface{}) error
9+
}

serviceprovider_factory.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package dependencyinjection
2+
3+
type IServiceProviderFactory interface {
4+
CreateServiceProvider() IServiceProvider
5+
}

0 commit comments

Comments
 (0)