Skip to content

Refactor/cost speed #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
36 changes: 28 additions & 8 deletions di/di.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,45 @@
package di

import (
"github.com/pubgo/dix/dix_internal"
"reflect"

"github.com/pubgo/dix/dixinternal"
)

var _dix = dix_internal.New(dix_internal.WithValuesNull())
var _dix = dixinternal.New(dixinternal.WithValuesNull())

// Example:
//
// c := di.New()
// c.Provide(func() *Config { return &Config{Endpoint: "localhost:..."} }) // Configuration
// c.Provide(NewDB) // Database connection
// c.Provide(NewHTTPServer) // Server
//
// c.Invoke(func(server *http.Server) { // Application startup
// server.ListenAndServe()
// })
//
// For more usage details, see the documentation for the Container type.

// Provide 注册对象构造器
// Provide registers an object constructor
func Provide(data any) {
_dix.Provide(data)
}

// Inject 注入对象
// Inject injects objects
//
// data: <*struct>或<func>
func Inject[T any](data T, opts ...dix_internal.Option) T {
_ = _dix.Inject(data, opts...)
// data: <*struct> or <func>
func Inject[T any](data T, opts ...dixinternal.Option) T {
vp := reflect.ValueOf(data)
if vp.Kind() == reflect.Struct {
_ = _dix.Inject(&data, opts...)
} else {
_ = _dix.Inject(data, opts...)
}
return data
}

// Graph Dix graph
func Graph() *dix_internal.Graph {
func Graph() *dixinternal.Graph {
return _dix.Graph()
}
18 changes: 9 additions & 9 deletions dix.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@ package dix

import (
"reflect"

"github.com/pubgo/dix/dix_internal"
"github.com/pubgo/dix/dixinternal"
)

const (
InjectMethodPrefix = dix_internal.InjectMethodPrefix
InjectMethodPrefix = dixinternal.InjectMethodPrefix
)

type (
Option = dix_internal.Option
Options = dix_internal.Options
Dix = dix_internal.Dix
Graph = dix_internal.Graph
Option = dixinternal.Option
Options = dixinternal.Options
Dix = dixinternal.Dix
Graph = dixinternal.Graph
)

func WithValuesNull() Option {
return dix_internal.WithValuesNull()
return dixinternal.WithValuesNull()
}

func New(opts ...Option) *Dix {
return dix_internal.New(opts...)
return dixinternal.New(opts...)
}

func Inject[T any](di *Dix, data T, opts ...Option) T {
Expand Down
21 changes: 0 additions & 21 deletions dix_internal/api.go

This file was deleted.

51 changes: 0 additions & 51 deletions dix_internal/graph.go

This file was deleted.

10 changes: 5 additions & 5 deletions dix_internal/aaa.go → dixinternal/aaa.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dix_internal
package dixinternal

import (
"reflect"
Expand All @@ -7,10 +7,10 @@ import (
)

const (
// defaultKey 默认的 namespace
// defaultKey default namespace
defaultKey = "default"

// InjectMethodPrefix 可以对对象进行 Inject, 只要这个对象的方法中包含了以`InjectMethodPrefix`为前缀的方法
// InjectMethodPrefix can inject objects, as long as the method of this object contains a prefix of `InjectMethodPrefix`
InjectMethodPrefix = "DixInject"
)

Expand All @@ -27,6 +27,6 @@ type Graph struct {

var logger = log.GetLogger("dix")

func SetLogLevel(lvl log.Level) {
logger = logger.WithLevel(lvl)
func SetLog(setter func(logger log.Logger) log.Logger) {
logger = setter(logger)
}
37 changes: 37 additions & 0 deletions dixinternal/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package dixinternal

import (
"reflect"

"github.com/pubgo/funk/assert"
"github.com/pubgo/funk/errors"
)

// New Dix new
func New(opts ...Option) *Dix {
return newDix(opts...)
}

func (x *Dix) Provide(param any) {
x.provide(param)
}

func (x *Dix) Inject(param any, opts ...Option) any {
if dep, ok := x.isCycle(); ok {
logger.Error().
Str("cycle_path", dep).
Str("component", reflect.TypeOf(param).String()).
Msg("dependency cycle detected")
assert.Must(errors.New("circular dependency: " + dep))
}

assert.Must(x.inject(param, opts...))
return param
}

func (x *Dix) Graph() *Graph {
return &Graph{
Objects: x.objectGraph(),
Providers: x.providerGraph(),
}
}
21 changes: 12 additions & 9 deletions dix_internal/cycle-check.go → dixinternal/cycle-check.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package dix_internal
package dixinternal

import (
"reflect"
Expand All @@ -7,14 +7,17 @@ import (

func (x *Dix) buildDependencyGraph() map[reflect.Type]map[reflect.Type]bool {
graph := make(map[reflect.Type]map[reflect.Type]bool)
for typ, nodes := range x.providers {
for _, n := range nodes {
if graph[typ] == nil {
graph[typ] = make(map[reflect.Type]bool)
}
for _, input := range n.input {
for _, provider := range x.getAllProvideInput(input.typ) {
graph[typ][provider.typ] = true
// Pre-allocate map capacity to reduce rehash
for outTyp := range x.providers {
graph[outTyp] = make(map[reflect.Type]bool)
}

// Build dependency graph
for outTyp, nodes := range x.providers {
for _, providerNode := range nodes {
for _, input := range providerNode.inputList {
for _, provider := range x.getProvideAllInputs(input.typ) {
graph[outTyp][provider.typ] = true
}
}
}
Expand Down
Loading
Loading