di

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 30, 2023 License: MIT Imports: 5 Imported by: 0

README

Golang 依赖注入

为什么我们需要依赖注入:

Most important, for me, is making it easy to follow the Single Responsibility Principle.

DI/IoC makes it simple for me to manage dependencies between objects. 
In turn, that makes it easier for me to break coherent functionality off into it's 
own contract (interface). 

As a result, my code has been far more modularized since I learned of DI/IoC.
Another result of this is that I can much more easily see my way through to a 
design that supports the Open-Closed Principle. This is one of the most confidence 
inspiring techniques (second only to automated testing). I doubt I could espouse the 
virtues of Open-Closed Principle enough.

DI/IoC is one of the few things in my programming career that has been a "game changer." 
There is a huge gap in quality between code I wrote before & after learning DI/IoC. 
Let me emphasize that some more. HUGE improvement in code quality.

安装

go get github.com/douyacun/go-ioc

用法

构造一个问候服务需要知道

  1. 向谁问候
  2. 问候什么
package simple

import (
	"fmt"
	di "github.com/douyacun/go-ioc"
	"testing"
)

type MessagePrinter interface {
	Print()
}

type UserProvider interface {
	GetUserName() string
}

type UserProviderImpl struct {
	UserName string `di:"userName"` // will match message
}

func (impl *UserProviderImpl) GetUserName() string {
	return impl.UserName
}

type MessagePrinterImpl struct {
	message string `di:"message"` // will match message
}

func (impl *MessagePrinterImpl) Print() {
	fmt.Println(impl.message)
}

func (impl *MessagePrinterImpl) SetMessage(m string) {
	impl.message = m
}

type GreeterService struct {
	UserProvider UserProvider   `di:"*"` // will match type
	Printer      MessagePrinter `di:"*"` // will match type
}

func (s *GreeterService) Print() {
	fmt.Printf("%s:", s.UserProvider.GetUserName())
	s.Printer.Print()
}

通常来说的初始化过程

message := "say hello"
printer := &MessagePrinterImpl{}
printer.SetMessage(message)

userName := "word"
userProvider := &UserProviderImpl{UserName: userName}

service := &MessagePrinterService{Printer: printer, UserProvider:userProvider}
service.Print()

使用依赖注入后

di.Register("message", "hello world")
di.Register("userName", "douyacun")
di.Register("printer", &MessagePrinterImpl{})
di.Register("userProvider", &UserProviderImpl{})

service := &GreeterService{}

di.MustBind(service)
service.Print()

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNotSupport = fmt.Errorf("dp bind should be used on struct")
)

Functions

func Bind

func Bind(target interface{}) error

func MustBind

func MustBind(target interface{})

func NewBinder

func NewBinder(target interface{}, registry *Ioc) *bind

func Register

func Register(name string, value interface{}, opts ...RegistryOption)

Types

type Ioc

type Ioc struct {
	// contains filtered or unexported fields
}

func NewRegistry

func NewRegistry() *Ioc

func (*Ioc) Bind

func (r *Ioc) Bind(target interface{}) error

func (*Ioc) FetchByName

func (r *Ioc) FetchByName(name string) (interface{}, error)

获取并填充所需对象

func (*Ioc) FetchByType

func (r *Ioc) FetchByType(t reflect.Type) (interface{}, error)

获取并填充所需对象

func (*Ioc) FuncMatchType

func (r *Ioc) FuncMatchType(v reflect.Value, target reflect.Type) bool

func (*Ioc) Register

func (r *Ioc) Register(name string, value interface{}, opts ...RegistryOption)

type RegistryOption

type RegistryOption func(*registryItem)

func WithNoBind

func WithNoBind() RegistryOption

type Tag

type Tag struct {
	// contains filtered or unexported fields
}

func (*Tag) AllowEmpty

func (tag *Tag) AllowEmpty() bool

func (*Tag) GetName

func (tag *Tag) GetName() string

func (*Tag) IsSkip

func (tag *Tag) IsSkip() bool

func (*Tag) ParseTag

func (tag *Tag) ParseTag(field reflect.StructField, tagStr string) *Tag

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL