架構學習之路(三)-- IOC

來源:互聯網
上載者:User

參考:
https://studygolang.com/articles/13783?fr=sidebar
https://studygolang.com/articles/7716
先寫著,我現在吃不透原理
一、IOC
Ioc的思想就是解耦,只依賴容器而不依賴具體的類,當你的類有修改時,最多需要改動一下容器相關代碼,業務代碼並不受影響。

golang的依賴注入原理

步驟如下:(golang不支援動態建立對象,所以需要先手動建立對象然後注入,java可以直接動態建立對象)

1.通過反射讀取對象的依賴(golang是通過tag實現)
2.在容器中尋找有無該對象執行個體
3.如果有該對象執行個體或者建立對象的Factory 方法,則注入對象或使用工廠建立對象並注入
4.如果無該對象執行個體,則報錯

代碼實現
package diimport (    "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()}// 設定執行個體對象工廠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}// 列印容器內部執行個體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")}
相關關鍵詞:
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.