亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

2. iocgo如何使用

2.1 iocgo包的安裝

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

go get github.com/studyzy/iocgo

2.2 使用示例與說明

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ù)。

接下來調(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ù)在通過容器獲得對(duì)應(yīng)的實(shí)例時(shí),應(yīng)該通過哪個(gè)Name去獲得對(duì)應(yīng)的實(shí)例。
  • Parameters 這個(gè)主要用于指定構(gòu)造函數(shù)中的某些非容器托管的參數(shù),比如某構(gòu)造函數(shù)中有int,string等參數(shù),而這些參數(shù)的實(shí)例是不需要通過ioc容器進(jìn)行映射托管的,那么就在這里直接指定。
  • Default 這個(gè)主要用于設(shè)置一個(gè)interface對(duì)應(yīng)的默認(rèn)的實(shí)例,也就是如果沒有指定Name的情況下,應(yīng)該找哪個(gè)實(shí)例。 關(guān)于每一個(gè)參數(shù)該如何使用,我都寫了UT樣例,具體參考: container_test.go

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

如果我們已經(jīng)有了某個(gè)對(duì)象的實(shí)例,那么可以將該實(shí)例和其想映射的interface直接注冊(cè)到ioc容器中,方便其他依賴的對(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)映射我們通過Register函數(shù)和RegisterInstance函數(shù)已經(jīng)注冊(cè)到容器中,接下來就需要從容器獲得指定的實(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等類型的不在ioc容器中托管的參數(shù),可以在這里指定。如果構(gòu)造函數(shù)本身需要這些參數(shù),而且在前面Register的時(shí)候已經(jīng)通過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,那么通過調(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ù)在通過ioc容器獲得實(shí)例時(shí)使用哪個(gè)name來獲得實(shí)例。 最后函數(shù)調(diào)用完成,如果函數(shù)本身有多個(gè)返回值,有error返回,那么Call函數(shù)也會(huì)返回對(duì)應(yīng)的結(jié)果。

2.3 參考:

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

3. 總結(jié)

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

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

相關(guān)文章

  • 一文詳解kubernetes?中資源分配的那些事

    一文詳解kubernetes?中資源分配的那些事

    這篇文章主要為大家介紹了kubernetes?中資源分配的那些事,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Windows+Linux系統(tǒng)下Go語言環(huán)境安裝配置過程

    Windows+Linux系統(tǒng)下Go語言環(huán)境安裝配置過程

    Go 語言被設(shè)計(jì)成一門應(yīng)用于搭載 Web 服務(wù)器,存儲(chǔ)集群或類似用途的巨型中央服務(wù)器的系統(tǒng)編程語言。這篇文章主要介紹了Windows+Linux系統(tǒng)下Go語言環(huán)境搭建配置過程,針對(duì)每種系統(tǒng)給大家講解的非常詳細(xì),需要的朋友可以參考下
    2021-06-06
  • 詳解如何使用Golang擴(kuò)展Envoy

    詳解如何使用Golang擴(kuò)展Envoy

    這篇文章主要為大家介紹了詳解如何使用Golang擴(kuò)展Envoy實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06
  • golang中接口對(duì)象的轉(zhuǎn)型兩種方式

    golang中接口對(duì)象的轉(zhuǎn)型兩種方式

    這篇文章主要介紹了golang中接口對(duì)象的轉(zhuǎn)型方式,大家都知道接口對(duì)象的轉(zhuǎn)型有兩種方式,文中通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-10-10
  • golang關(guān)閉chan通道的方法示例

    golang關(guān)閉chan通道的方法示例

    在go語言中,通道(channel)是一個(gè)非常重要的概念,通道提供了一種在不同 goroutine 之間安全地傳遞數(shù)據(jù)的方式,在本文中,我們將討論如何關(guān)閉通道以及在關(guān)閉通道時(shí)需要考慮的事項(xiàng),需要的朋友可以參考下
    2024-02-02
  • Go?Redis客戶端使用的兩種對(duì)比

    Go?Redis客戶端使用的兩種對(duì)比

    這篇文章主要為大家介紹了Go?Redis客戶端使用對(duì)比詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • gin使用自定義結(jié)構(gòu)綁定表單數(shù)據(jù)的示例代碼

    gin使用自定義結(jié)構(gòu)綁定表單數(shù)據(jù)的示例代碼

    這篇文章主要介紹了gin使用自定義結(jié)構(gòu)綁定表單數(shù)據(jù)的示例代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • 一文讀懂go中semaphore(信號(hào)量)源碼

    一文讀懂go中semaphore(信號(hào)量)源碼

    這篇文章主要介紹了一文讀懂go中semaphore(信號(hào)量)源碼的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Golang 實(shí)現(xiàn) Redis系列(六)如何實(shí)現(xiàn) pipeline 模式的 redis 客戶端

    Golang 實(shí)現(xiàn) Redis系列(六)如何實(shí)現(xiàn) pipeline 模式的 redis 客戶端

    pipeline 模式的 redis 客戶端需要有兩個(gè)后臺(tái)協(xié)程負(fù)責(zé) tcp 通信,調(diào)用方通過 channel 向后臺(tái)協(xié)程發(fā)送指令,并阻塞等待直到收到響應(yīng),本文是使用 golang 實(shí)現(xiàn) redis 系列的第六篇, 將介紹如何實(shí)現(xiàn)一個(gè) Pipeline 模式的 Redis 客戶端。
    2021-07-07
  • go語言區(qū)塊鏈學(xué)習(xí)調(diào)用智能合約

    go語言區(qū)塊鏈學(xué)習(xí)調(diào)用智能合約

    這篇文章主要為大家介紹了go語言區(qū)塊鏈學(xué)習(xí)中如何調(diào)用智能合約的實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-10-10

最新評(píng)論