真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

golang不到30行代碼實現(xiàn)依賴注入的方法-創(chuàng)新互聯(lián)

本文介紹了golang不到30行代碼實現(xiàn)依賴注入的方法,分享給大家,具體如下:

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)峨眉山,十多年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575

項目地址

go-di-demo

本項目依賴

使用標(biāo)準(zhǔn)庫實現(xiàn),無額外依賴

依賴注入的優(yōu)勢

用java的人對于spring框架一定不會陌生,spring核心就是一個IoC(控制反轉(zhuǎn)/依賴注入)容器,帶來一個很大的優(yōu)勢是解耦。一般只依賴容器,而不依賴具體的類,當(dāng)你的類有修改時,最多需要改動一下容器相關(guān)代碼,業(yè)務(wù)代碼并不受影響。

golang的依賴注入原理

總的來說和java的差不多,步驟如下:(golang不支持動態(tài)創(chuàng)建對象,所以需要先手動創(chuàng)建對象然后注入,java可以直接動態(tài)創(chuàng)建對象)

  • 通過反射讀取對象的依賴(golang是通過tag實現(xiàn))
  • 在容器中查找有無該對象實例
  • 如果有該對象實例或者創(chuàng)建對象的工廠方法,則注入對象或使用工廠創(chuàng)建對象并注入
  • 如果無該對象實例,則報錯

代碼實現(xiàn)

一個典型的容器實現(xiàn)如下,依賴類型參考了spring的singleton/prototype,分別對象單例對象和實例對象:

package di

import (
 "sync"
 "reflect"
 "fmt"
 "strings"
 "errors"
)

var (
 ErrFactoryNotFound = errors.New("factory not found")
)

type factory = func() (interface{}, error)
// 容器
type Container struct {
 sync.Mutex
 singletons map[string]interface{}
 factories map[string]factory
}
// 容器實例化
func NewContainer() *Container {
 return &Container{
  singletons: make(map[string]interface{}),
  factories: make(map[string]factory),
 }
}

// 注冊單例對象
func (p *Container) SetSingleton(name string, singleton interface{}) {
 p.Lock()
 p.singletons[name] = singleton
 p.Unlock()
}

// 獲取單例對象
func (p *Container) GetSingleton(name string) interface{} {
 return p.singletons[name]
}

// 獲取實例對象
func (p *Container) GetPrototype(name string) (interface{}, error) {
 factory, ok := p.factories[name]
 if !ok {
  return nil, ErrFactoryNotFound
 }
 return factory()
}

// 設(shè)置實例對象工廠
func (p *Container) SetPrototype(name string, factory factory) {
 p.Lock()
 p.factories[name] = factory
 p.Unlock()
}

// 注入依賴
func (p *Container) Ensure(instance interface{}) error {
 elemType := reflect.TypeOf(instance).Elem()
 ele := reflect.ValueOf(instance).Elem()
 for i := 0; i < elemType.NumField(); i++ { // 遍歷字段
  fieldType := elemType.Field(i)
  tag := fieldType.Tag.Get("di") // 獲取tag
  diName := p.injectName(tag)
  if diName == "" {
   continue
  }
  var (
   diInstance interface{}
   err  error
  )
  if p.isSingleton(tag) {
   diInstance = p.GetSingleton(diName)
  }
  if p.isPrototype(tag) {
   diInstance, err = p.GetPrototype(diName)
  }
  if err != nil {
   return err
  }
  if diInstance == nil {
   return errors.New(diName + " dependency not found")
  }
  ele.Field(i).Set(reflect.ValueOf(diInstance))
 }
 return nil
}

// 獲取需要注入的依賴名稱
func (p *Container) injectName(tag string) string {
 tags := strings.Split(tag, ",")
 if len(tags) == 0 {
  return ""
 }
 return tags[0]
}

// 檢測是否單例依賴
func (p *Container) isSingleton(tag string) bool {
 tags := strings.Split(tag, ",")
 for _, name := range tags {
  if name == "prototype" {
   return false
  }
 }
 return true
}

// 檢測是否實例依賴
func (p *Container) isPrototype(tag string) bool {
 tags := strings.Split(tag, ",")
 for _, name := range tags {
  if name == "prototype" {
   return true
  }
 }
 return false
}

// 打印容器內(nèi)部實例
func (p *Container) String() string {
 lines := make([]string, 0, len(p.singletons)+len(p.factories)+2)
 lines = append(lines, "singletons:")
 for name, item := range p.singletons {
  line := fmt.Sprintf(" %s: %x %s", name, &item, reflect.TypeOf(item).String())
  lines = append(lines, line)
 }
 lines = append(lines, "factories:")
 for name, item := range p.factories {
  line := fmt.Sprintf(" %s: %x %s", name, &item, reflect.TypeOf(item).String())
  lines = append(lines, line)
 }
 return strings.Join(lines, "\n")
}

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


分享標(biāo)題:golang不到30行代碼實現(xiàn)依賴注入的方法-創(chuàng)新互聯(lián)
分享鏈接:http://weahome.cn/article/jhpig.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部