Skip to content

Commit

Permalink
Update xdi
Browse files Browse the repository at this point in the history
  • Loading branch information
onanying committed Oct 31, 2023
1 parent 2adae3a commit 89e2c98
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 252 deletions.
201 changes: 0 additions & 201 deletions src/xdi/LICENSE

This file was deleted.

14 changes: 6 additions & 8 deletions src/xdi/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
> OpenMix 出品:[https://openmix.org](https://openmix.org/mix-go)
> Produced by OpenMix: [https://openmix.org](https://openmix.org/mix-go)
## Mix XDI

DI、IoC 容器

DI, IoC container

## Overview

一个创建对象以及处理对象依赖关系的库,该库可以实现统一管理依赖,全局对象管理,动态配置刷新等。
A library for creating objects and managing their dependencies. This library can be used for managing dependencies in a unified way, managing global objects, and refreshing dynamic configurations.

## Installation

Expand All @@ -18,7 +16,7 @@ go get github.com/mix-go/xdi

## Quick start

通过依赖配置实例化一个单例
Create a singleton through dependency configuration

```go
package main
Expand Down Expand Up @@ -54,7 +52,7 @@ func main() {

## Reference

依赖配置中引用另一个依赖配置的实例
Refer to another dependency configuration instance in the dependency configuration

```go
package main
Expand Down Expand Up @@ -112,10 +110,10 @@ func main() {

## Refresh singleton

程序执行中配置信息发生变化时,`Refresh()` 可以刷新单例的实例来切换使用新的配置,通常在微服务配置中心中使用。
When the configuration information changes during program execution, `Refresh()` can refresh the singleton instance to switch to using the new configuration. It is commonly used in microservice configuration centers.

```go
obj, err := xdi.Container().Object("foo")
obj, err := xdi.DefaultContainer.Object("foo")
if err != nil {
panic(err)
}
Expand Down
64 changes: 25 additions & 39 deletions src/xdi/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,31 @@ import (
"sync"
)

var iContainer *container
var DefaultContainer *Container

func init() {
iContainer = New()
DefaultContainer = New()
}

// New
func New() *container {
return &container{}
func New() *Container {
return &Container{}
}

// Container
func Container() *container {
return iContainer
}

// Provide
func Provide(objects ...*Object) error {
return iContainer.Provide(objects...)
return DefaultContainer.Provide(objects...)
}

// Populate
func Populate(name string, ptr interface{}) error {
return iContainer.Populate(name, ptr)
return DefaultContainer.Populate(name, ptr)
}

// container
type container struct {
type Container struct {
Objects []*Object
tidyObjects sync.Map
instances sync.Map
}

// Provide
func (t *container) Provide(objects ...*Object) error {
func (t *Container) Provide(objects ...*Object) error {
for _, o := range objects {
if _, ok := t.tidyObjects.Load(o.Name); ok {
return fmt.Errorf("error: object '%s' existing", o.Name)
Expand All @@ -50,8 +40,7 @@ func (t *container) Provide(objects ...*Object) error {
return nil
}

// Object
func (t *container) Object(name string) (*Object, error) {
func (t *Container) Object(name string) (*Object, error) {
v, ok := t.tidyObjects.Load(name)
if !ok {
return nil, fmt.Errorf("error: object '%s' not found", name)
Expand All @@ -60,8 +49,7 @@ func (t *container) Object(name string) (*Object, error) {
return obj, nil
}

// Populate
func (t *container) Populate(name string, ptr interface{}) error {
func (t *Container) Populate(name string, ptr interface{}) error {
obj, err := t.Object(name)
if err != nil {
return err
Expand All @@ -76,29 +64,27 @@ func (t *container) Populate(name string, ptr interface{}) error {
return nil
}
// 处理并发穿透
var e error
obj.once.Do(func() {
v, err := obj.New()
if err != nil {
e = err
return
}
t.instances.Store(name, v)
refresher.off()
})
if e != nil {
obj.once = sync.Once{}
return e
obj.mutex.Lock()
defer obj.mutex.Unlock()
p, ok := t.instances.Load(name)
if ok {
ptrCopy(ptr, p)
return nil
}
v, err := obj.New()
if err != nil {
return err
}
p, _ := t.instances.Load(name)
ptrCopy(ptr, p)
return e
t.instances.Store(name, v)
refresher.off()
ptrCopy(ptr, v)
return nil
} else {
v, err := obj.New()
if err != nil {
return err
}
ptrCopy(ptr, v)
return nil
}
return nil
}
Loading

0 comments on commit 89e2c98

Please sign in to comment.