golang IoC

hiword發表於2019-09-29

簡介

用慣了LaravelIoc,物件獲取變得那麼自然,初用Go,各struct,func都要自己解析
一堆NewFunc,索性自己搞了個ioc
參見Github(https://github.com/firmeve/firmeve)

物件繫結

f := NewFirmeve()

標量繫結

f.Bind(`bool`, false)
f.Bind(`string`, "string")

Struct 繫結

假設我們有如下struct

type Foo struct {
    Bar string 
}

func NewFoo(bar string) Foo{
    return Foo{Bar:bar}
}

我們將foo繫結進我們的容器中

f.Bind(`foo`,NewFoo("abc"))

Prt 繫結

繫結prtstruct型別是我們最常用的一種方式,請看下面的示例\

type Baz struct {
    Baz string 
}

func NewBaz() *Baz {
   return &Baz{}
}

f.Bind(`baz`, NewBaz())

函式繫結

func NewFoo() Foo{
   return Foo{Bar:"default string"}
}

f.Bind(`foo`, NewFoo)

使用Firmeve在繫結的時候暫時不支援引數注入
注意:如果是非函式型別繫結,則會預設為單例項型別

已繫結值覆蓋

我們通過WithBindCover(true)方法可以輕鬆設定覆蓋引數

f.Bind(`bool`, false)
fmt.Printf("%t",f.Get(`bool`))
f.Bind(`bool`, true, WithBindCover(true))
fmt.Printf("%t",f.Get(`bool`))

物件獲取

驗證物件是否存在

在不確定容器中是否包含此物件時,請使用Has方法進行判斷

f.Has(`foo`)

物件獲取

直接獲取容器中的值

f.Get(`foo`)

注意:如果指的定的key不存在,則會丟擲panic錯誤

新物件獲取

func NewFoo() Foo{
   return Foo{Bar:"default string"}
}

f.Bind(`foo`, NewFoo)
fmt.Printf("%p\n",f.Get("foo"))
fmt.Printf("%p\n",f.Get("foo"))
fmt.Printf("%p\n",f.Get("foo"))

Firmeve中,如果需要每次重新得到一個新的結構體物件
必須繫結一個函式值,否則得到的將是一個單例項

單例獲取

func NewFoo() Foo{
   return Foo{Bar:"default string"}
}

f.Bind(`foo`, NewFoo())
fmt.Printf("%p\n",f.Get("foo"))
fmt.Printf("%p\n",f.Get("foo"))
fmt.Printf("%p\n",f.Get("foo"))

引數解析

函式自動解析

讓我們來看一個簡單的示例

type PersonName struct {
   Name string
}

func NewPersonName() PersonName {
   return PersonName{Name: "Firmeve"}
}

type PersonAge struct {
   Age int
}

func PersonAge() *PersonAge {
   return &PersonAge{Age: 1}
}

type Person struct {
   name PersonName
   age *PersonAge
}

func NewPerson(name PersonName,age *PersonAge) *NewPerson {
    return NewPerson{
       name: name
       age: age
    }
}

f.Bind("PersonName", NewPersonName)
f.Bind("PersonAge", PersonAge)
fmt.Printf("%#v", f.Resolve(NewPerson))

結構體tag自動解析

現在,讓我們修改下上面的Person

type Person struct {
   Name PersonName `inject:"PersonName"`
   Age *PersonAge `inject:"PersonAge"`
   age1 *PersonAge `inject:"PersonAge"`
}

然後我們使用new函式直接建立一個新的結構體指標

fmt.Printf("%#v", new(NewPerson))

注意:此時 Person中的Name欄位並不是指標型別,而age1不符合structtag規範,所以Firmeve都會自動忽略。

來源:https://blog.crcms.cn/2019/09/29/go-ioc/

本作品採用《CC 協議》,轉載必須註明作者和本文連結