最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang輕量級(jí)IoC容器安裝使用示例

 更新時(shí)間:2022年06月24日 08:35:59   作者:深藍(lán)studyzy  
這篇文章主要為大家介紹了Golang輕量級(jí)IoC容器安裝使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1. iocgo簡(jiǎn)介

習(xí)慣于Java或者C#開(kāi)發(fā)的人應(yīng)該對(duì)控制反轉(zhuǎn)與依賴(lài)注入應(yīng)該再熟悉不過(guò)了。在Java平臺(tái)有鼎鼎大名的Spring框架,在C#平臺(tái)有Autofac,Unity,Windsor等,我當(dāng)年C#開(kāi)發(fā)時(shí)用的最多的就是Windsor。使用IoC容器是面向?qū)ο箝_(kāi)發(fā)中非常方便的解耦模塊之間的依賴(lài)的方法。各個(gè)模塊之間不依賴(lài)于實(shí)現(xiàn),而是依賴(lài)于接口,然后在構(gòu)造函數(shù)或者屬性或者方法中注入特定的實(shí)現(xiàn),方便了各個(gè)模塊的拆分以及模塊的獨(dú)立單元測(cè)試。

在[長(zhǎng)安鏈]的設(shè)計(jì)中,各個(gè)模塊可以靈活組裝,模塊之間的依賴(lài)基于protocol中定義的接口,每個(gè)接口有一個(gè)或者多個(gè)官方實(shí)現(xiàn),當(dāng)然第三方也可以提供該接口更多的實(shí)現(xiàn)。為了實(shí)現(xiàn)更靈活的組裝各個(gè)模塊,管理各個(gè)模塊的依賴(lài)關(guān)系,于是我寫(xiě)了iocgo這個(gè)輕量級(jí)的golang版Ioc容器。

2. iocgo如何使用

2.1 iocgo包的安裝

現(xiàn)在go官方版本已經(jīng)出到1.17了,當(dāng)然我在代碼中其實(shí)也沒(méi)有用什么新版本的新特性,于是就用1.15版本或者之后的Go版本即可。要使用iocgo包,直接通過(guò)go get添加到項(xiàng)目中:

go get github.com/studyzy/iocgo

2.2 使用示例與說(shuō)明

2.2.1 最簡(jiǎn)單的例子:

type Fooer interface {
	Foo(int)
}
type Foo struct {
}
func (Foo)Foo(i int)  {
	fmt.Println("foo:",i)
}
type Barer interface {
	Bar(string)
}
type Bar struct {
}
func (Bar) Bar(s string){
	fmt.Println("bar:",s)
}
type Foobarer interface {
	Say(int,string)
}
type Foobar struct {
	foo Fooer
	bar Barer
}
func NewFoobar(f Fooer,b Barer) Foobarer{
	return &Foobar{
		foo: f,
		bar: b,
	}
}
func (f Foobar)Say(i int ,s string)  {
	f.foo.Foo(i)
	f.bar.Bar(s)
}
func TestContainer_SimpleRegister(t *testing.T) {
	container := NewContainer()
	container.Register(NewFoobar)
	container.Register(func() Fooer { return &Foo{} })
	container.Register(func() Barer { return &Bar{} })
	var fb Foobarer
	container.Resolve(&fb)
	fb.Say(123,"Hello World")
}

這里我使用NewContainer()創(chuàng)建了一個(gè)新的容器,然后在容器中調(diào)用Register方法注冊(cè)了3個(gè)接口和對(duì)應(yīng)的構(gòu)造函數(shù),分別是:

  • Foobarer接口對(duì)應(yīng)NewFoobar(f Fooer,b Barer)構(gòu)造函數(shù)
  • Fooer接口對(duì)應(yīng)構(gòu)造&Foo{}的匿名函數(shù)。
  • Barer接口對(duì)應(yīng)構(gòu)造&Bar{}的匿名函數(shù)。

接下來(lái)調(diào)用Resolve函數(shù),并傳入var fb Foobarer 這個(gè)接口變量的指針,iocgo就會(huì)自動(dòng)去構(gòu)建Foobarer對(duì)應(yīng)的實(shí)例,并最終將實(shí)例賦值到fb這個(gè)變量上,于是最后我們就可以正常調(diào)用fb.Say實(shí)例方法了。

2.22. Register 的選項(xiàng)

iocgo的注冊(cè)interface到對(duì)象的函數(shù)定義如下:

func Register(constructor interface{}, options ...Option) error

iocgo為Register函數(shù)提供了以下參數(shù)選項(xiàng)可根據(jù)實(shí)際情況選擇性使用:

  • Name 為某個(gè)interface->對(duì)象的映射命名
  • Optional 表名這個(gè)構(gòu)造函數(shù)中哪些注入的interface參數(shù)是可選的,如果是可選,那么就算找不到interface對(duì)應(yīng)的實(shí)例也不會(huì)報(bào)錯(cuò)。
  • Interface 顯式聲明這個(gè)構(gòu)造函數(shù)返回的實(shí)例是映射到哪個(gè)interface。
  • Lifestyle(isTransient) 聲明這個(gè)構(gòu)造函數(shù)在構(gòu)造實(shí)例后是構(gòu)造的臨時(shí)實(shí)例還是單例實(shí)例,如果是臨時(shí)實(shí)例,那么下次再獲取該interface對(duì)應(yīng)的實(shí)例時(shí)需要再次調(diào)用構(gòu)造函數(shù),如果是單例,那么就緩存實(shí)例到容器中,下次再想獲得interface對(duì)應(yīng)的實(shí)例時(shí)直接使用緩存中的,不需要再次構(gòu)造。
  • DependsOn 這個(gè)主要是指定構(gòu)造函數(shù)中的某個(gè)參數(shù)在通過(guò)容器獲得對(duì)應(yīng)的實(shí)例時(shí),應(yīng)該通過(guò)哪個(gè)Name去獲得對(duì)應(yīng)的實(shí)例。
  • Parameters 這個(gè)主要用于指定構(gòu)造函數(shù)中的某些非容器托管的參數(shù),比如某構(gòu)造函數(shù)中有int,string等參數(shù),而這些參數(shù)的實(shí)例是不需要通過(guò)ioc容器進(jìn)行映射托管的,那么就在這里直接指定。
  • Default 這個(gè)主要用于設(shè)置一個(gè)interface對(duì)應(yīng)的默認(rèn)的實(shí)例,也就是如果沒(méi)有指定Name的情況下,應(yīng)該找哪個(gè)實(shí)例。 關(guān)于每一個(gè)參數(shù)該如何使用,我都寫(xiě)了UT樣例,具體參考: container_test.go

2.2.3. 注冊(cè)實(shí)例

如果我們已經(jīng)有了某個(gè)對(duì)象的實(shí)例,那么可以將該實(shí)例和其想映射的interface直接注冊(cè)到ioc容器中,方便其他依賴(lài)的對(duì)象獲取,RegisterInstance函數(shù)定義如下:

RegisterInstance(interfacePtr interface{}, instance interface{}, options ...Option) error 

使用上也很簡(jiǎn)單,直接將實(shí)例對(duì)應(yīng)的interface的指針作為參數(shù)1,實(shí)例本身作為參數(shù)2,傳入RegisterInstance即可:

b := &Bar{}
var bar Barer //interface
container.RegisterInstance(&bar, b) // register interface -> instance

2.2.4. 獲得實(shí)例

相關(guān)映射我們通過(guò)Register函數(shù)和RegisterInstance函數(shù)已經(jīng)注冊(cè)到容器中,接下來(lái)就需要從容器獲得指定的實(shí)例了。獲得實(shí)例需要調(diào)用函數(shù):

func Resolve(abstraction interface{}, options ...ResolveOption) error

這里第一個(gè)參數(shù)abstraction是我們想要獲取的某個(gè)interface的指針,第二個(gè)參數(shù)是可選參數(shù),目前提供的選項(xiàng)有:

  • ResolveName 指定使用哪個(gè)name的interface和實(shí)例的映射,如果不指定,那么就是默認(rèn)映射。
  • Arguments 指定在調(diào)用對(duì)應(yīng)的構(gòu)造函數(shù)獲得實(shí)例時(shí),傳遞的參數(shù),比如int,string等類(lèi)型的不在ioc容器中托管的參數(shù),可以在這里指定。如果構(gòu)造函數(shù)本身需要這些參數(shù),而且在前面Register的時(shí)候已經(jīng)通過(guò)Parameters選項(xiàng)進(jìn)行了指定,那么這里新的指定會(huì)覆蓋原有Register的指定。
var fb Foobarer
err:=container.Resolve(&fb)

另外如果我們的構(gòu)造函數(shù)return的值中支持error,而且實(shí)際構(gòu)造的時(shí)候確實(shí)返回了error,那么Resolve函數(shù)也會(huì)返回對(duì)應(yīng)的這個(gè)err。

特別注意:Resolve的第一個(gè)參數(shù)是申明的某個(gè)interface的指針,一定要是指針,不能直接傳interface

2.2.5. 結(jié)構(gòu)體參數(shù)和字段填充

有些時(shí)候構(gòu)造函數(shù)的入?yún)⒎浅6?,于是我們可以申明一個(gè)結(jié)構(gòu)體,把所有入?yún)⒍挤湃脒@個(gè)結(jié)構(gòu)體中,這樣構(gòu)造函數(shù)就只需要一個(gè)參數(shù)了。iocgo也支持自動(dòng)填充這個(gè)結(jié)構(gòu)體中interface對(duì)應(yīng)的實(shí)例,從而構(gòu)造新的對(duì)象。另外iocgo也提供了Fill方法,可以直接填充某個(gè)結(jié)構(gòu)體,比如:

type FoobarInput struct {
	foo Fooer
	bar Barer
	msg string
}
input := FoobarInput{
		msg: "studyzy",
	}
	container.Register(func() Fooer { return &Foo{} })
	container.Register(func() Barer { return &Bar{} })
	err := container.Fill(&input)

結(jié)構(gòu)體中的字段還支持tag,目前提供的tag有兩種:

  • name //指定這個(gè)字段在獲得對(duì)應(yīng)的實(shí)例時(shí)使用的name
  • optional //指定這個(gè)字段是否是可選的,如果是,那么就算獲得不到對(duì)應(yīng)的實(shí)例,也不會(huì)報(bào)錯(cuò)。 示例example:
type FoobarInputWithTag struct {
	foo Fooer `optional:"true"`
	bar Barer `name:"baz"`
	msg string
}

2.2.6. 函數(shù)調(diào)用

除了構(gòu)造函數(shù)注入之外,iocgo也支持函數(shù)注入,我們申明一個(gè)函數(shù),這個(gè)函數(shù)的參數(shù)中有些參數(shù)是interface,那么通過(guò)調(diào)用iocgo中的Call方法,可以為這個(gè)函數(shù)注入對(duì)應(yīng)的實(shí)例作為參數(shù),并最終完成函數(shù)的調(diào)用。 示例 example:

func SayHi1(f Fooer, b Barer) {
	f.Foo(1234)
	b.Bar("hi")
}
Register(func() Fooer { return &Foo{} })
Register(func() Barer { return &Bar{} })
Call(SayHi1)

Call函數(shù)也是支持選項(xiàng)的,目前提供了2個(gè)選項(xiàng):

  • CallArguments 指定函數(shù)中某個(gè)參數(shù)的值
  • CallDependsOn 指定函數(shù)中某個(gè)參數(shù)在通過(guò)ioc容器獲得實(shí)例時(shí)使用哪個(gè)name來(lái)獲得實(shí)例。 最后函數(shù)調(diào)用完成,如果函數(shù)本身有多個(gè)返回值,有error返回,那么Call函數(shù)也會(huì)返回對(duì)應(yīng)的結(jié)果。

2.3 參考:

在寫(xiě)這個(gè)iocgo的代碼時(shí),主要參考了以下兩個(gè)Ioc相關(guān)的項(xiàng)目:

3. 總結(jié)

iocgo是一個(gè)純Golang語(yǔ)言開(kāi)發(fā)的用于管理依賴(lài)注入的IoC容器,使用這個(gè)容器可以很好的實(shí)現(xiàn)go語(yǔ)言下的面向?qū)ο箝_(kāi)發(fā),模塊解耦。現(xiàn)已經(jīng)開(kāi)源,歡迎大家使用,開(kāi)源地址:https://github.com/studyzy/iocgo

以上就是Golang輕量級(jí)IoC容器安裝使用示例的詳細(xì)內(nèi)容,更多關(guān)于Golang輕量級(jí)IoC容器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • GoLang sync.Pool簡(jiǎn)介與用法

    GoLang sync.Pool簡(jiǎn)介與用法

    這篇文章主要介紹了GoLang sync.Pool簡(jiǎn)介與用法,Pool是可伸縮、并發(fā)安全的臨時(shí)對(duì)象池,用來(lái)存放已經(jīng)分配但暫時(shí)不用的臨時(shí)對(duì)象,通過(guò)對(duì)象重用機(jī)制,緩解GC壓力,提高程序性能
    2023-01-01
  • Go語(yǔ)言CSP并發(fā)模型實(shí)現(xiàn)MPG

    Go語(yǔ)言CSP并發(fā)模型實(shí)現(xiàn)MPG

    這篇文章主要為大家介紹了Go語(yǔ)言CSP并發(fā)模型實(shí)現(xiàn)MPG圖文詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Golang使用切片實(shí)現(xiàn)單鏈表的示例代碼

    Golang使用切片實(shí)現(xiàn)單鏈表的示例代碼

    單鏈表(Single?Linked?List)是鏈表數(shù)據(jù)結(jié)構(gòu)的一種實(shí)現(xiàn)方式,它包含一系列節(jié)點(diǎn)(Node),每個(gè)節(jié)點(diǎn)都包含一個(gè)數(shù)據(jù)域和一個(gè)指向下一個(gè)節(jié)點(diǎn)的指針,本文給大家介紹了Golang使用切片實(shí)現(xiàn)單鏈表的操作,需要的朋友可以參考下
    2024-05-05
  • Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試詳解

    Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試詳解

    這篇文章主要為大家介紹了Go語(yǔ)言處理超大字符串型整數(shù)加減經(jīng)典面試示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • Go實(shí)現(xiàn)生產(chǎn)隨機(jī)密碼的示例代碼

    Go實(shí)現(xiàn)生產(chǎn)隨機(jī)密碼的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Go實(shí)現(xiàn)生產(chǎn)隨機(jī)密碼的,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2023-09-09
  • Golang Http 驗(yàn)證碼示例實(shí)現(xiàn)

    Golang Http 驗(yàn)證碼示例實(shí)現(xiàn)

    這篇文章主要介紹了Golang Http 驗(yàn)證碼示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • GO日志打印如何添加goroutineid

    GO日志打印如何添加goroutineid

    今天想給日志添加一個(gè)前綴,以區(qū)分不同goroutine的日志,方便做并發(fā)問(wèn)題的排查,做日志跟蹤,下面給大家分享GO日志打印如何添加goroutineid,感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • 并發(fā)安全本地化存儲(chǔ)go-cache讀寫(xiě)鎖實(shí)現(xiàn)多協(xié)程并發(fā)訪(fǎng)問(wèn)

    并發(fā)安全本地化存儲(chǔ)go-cache讀寫(xiě)鎖實(shí)現(xiàn)多協(xié)程并發(fā)訪(fǎng)問(wèn)

    這篇文章主要介紹了并發(fā)安全本地化存儲(chǔ)go-cache讀寫(xiě)鎖實(shí)現(xiàn)多協(xié)程并發(fā)訪(fǎng)問(wèn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 一文帶你了解Go語(yǔ)言中的指針和結(jié)構(gòu)體

    一文帶你了解Go語(yǔ)言中的指針和結(jié)構(gòu)體

    前面的兩篇文章對(duì)?Go?語(yǔ)言的基礎(chǔ)語(yǔ)法和基本數(shù)據(jù)類(lèi)型以及幾個(gè)復(fù)合數(shù)據(jù)類(lèi)型進(jìn)行介紹,本文將對(duì)?Go?里面的指針和結(jié)構(gòu)體進(jìn)行介紹,也為后續(xù)文章做鋪墊,感興趣的可以了解一下
    2022-11-11
  • 詳解Golang中的Mutex并發(fā)原語(yǔ)

    詳解Golang中的Mutex并發(fā)原語(yǔ)

    Mutex?是?Go?語(yǔ)言中互斥鎖的實(shí)現(xiàn),它是一種同步機(jī)制,用于控制多個(gè)?goroutine?之間的并發(fā)訪(fǎng)問(wèn)。本文將著重介紹?Go?的?Mutex?并發(fā)原語(yǔ),希望對(duì)大家有所幫助
    2023-03-03

最新評(píng)論

杭州市| 泸定县| 木里| 光泽县| 榆社县| 鱼台县| 宁南县| 来凤县| 依安县| 洱源县| 那坡县| 郁南县| 黄骅市| 图木舒克市| 揭东县| 定兴县| 洞口县| 安平县| 城步| 交口县| 拉孜县| 商丘市| 尚义县| 资源县| 响水县| 台州市| 宝山区| 固安县| 卓尼县| 海南省| 垦利县| 肥乡县| 仙游县| 涡阳县| 象州县| 宁南县| 五华县| 松潘县| 蓝田县| 福泉市| 琼结县|