Go 言語における依存関係注入 (DI) は、コンポーネント間の依存関係を分離する設計パターンであり、必要に応じて、さまざまなコンポーネントが、統一されたインターフェイス (オブジェクトと状態) を通じて他のコンポーネントから情報を取得できます。依存関係注入の利点は分離にあり、分離により、コードのスケーラビリティの強化、コードの保守性の強化、単体テストの容易化など、さらなる利点がもたらされます。
このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。
Inversion of Control (IOC Inversion Of Control) と呼ばれ、この第三者は IOC コンテナと呼ばれます。 IOC コンテナがしなければならないことは、新しい B を作成し、この B のインスタンスを A に注入することです。その後、A は通常、B に基づいたメソッドを使用できます。このプロセスは依存関係の注入と呼ばれ、IOC に基づいてこのメソッドはと呼ばれます。依存性の注入。
簡単に言うと、依存関係注入 (DI) は、コンポーネント間の依存関係を分離する設計パターンです。必要に応じて、さまざまなコンポーネントが、統一されたインターフェイスを通じて他のコンポーネントのオブジェクトや状態を取得できます。 Go 言語のインターフェイス設計により、サードパーティの依存関係注入フレームワーク (Java など) を使用する必要がある多くの状況が回避されます。当社の注入ソリューションは、Dager や Guice と同様の注入ソリューションをごくわずかしか提供せず、オブジェクトとコンポーネント間の依存関係の手動構成を回避することに重点を置いています。wire は、Google がオープンソース化した依存関係注入ツールです。特別な
go ファイル内の型間の依存関係を
wire に伝えるだけで、自動的にヘルプが表示されます。コードを生成し、指定されたタイプのオブジェクトの作成を支援し、その依存関係を組み立てます。
wire には、
Provider (コンストラクター) と
Injector (インジェクター) という 2 つの基本概念があります。
provider を提供して、これらの依存オブジェクトを生成する方法を
wire に知らせます。
wire 定義した
injector 関数シグネチャに従って、完全な
injector 関数が生成されます。
injector 関数は、必要な最後の関数です。依存関係の順序で
provider を呼び出します。
wire の要件は非常に簡単で、新しい
wire.go ファイルを作成し (ファイル名は任意です)、初期化関数を作成します。たとえば、
Mission オブジェクトを作成して初期化したい場合は、次のように実行できます:
//+build wireinject package main import "github.com/google/wire" func InitMission(name string) Mission { wire.Build(NewMonster, NewPlayer, NewMission) return Mission{} }
最初の行に build Wireinject という注釈があり、これがインジェクターであることを示しています。 build
は実際には Go 言語の機能です。 C/C 条件付きコンパイルと同様に、go build
の実行時にいくつかのオプションを渡すことができ、これらのオプションに基づいて特定のファイルをコンパイルするかどうかが決定されます。 wire
ツールは wireinject
を含むファイルのみを処理するため、wire.go
ファイルにこれを追加する必要があります。
関数では、wire.Build()
を呼び出して、Mission
が依存する型のコンストラクターを渡します。たとえば、NewMission()
を呼び出して Mission
型を作成する必要があります。NewMission()
は 2 つのパラメータ (Monster
の 1 つ) を受け入れます。タイプと Player
タイプのいずれか。 Monster
タイプのオブジェクトは NewMonster()
を呼び出して作成する必要があり、Player
タイプのオブジェクトは NewPlayer()
を呼び出して作成する必要があります。 。したがって、NewMonster()
と NewPlayer()
も wire
に渡す必要があります。
wire.go ファイルを作成し、wire コマンドを実行すると、wire_gen.go ファイルが自動的に生成されます。
// Code generated by Wire. DO NOT EDIT. //go:generate wire //+build !wireinject package main // Injectors from wire.go: func InitMission(name string) Mission { player := NewPlayer(name) monster := NewMonster() mission := NewMission(player, monster) return mission }
wire が自動的に InitMission メソッドを生成していることがわかります。このメソッドでは、プレイヤー、モンスター、ミッションが順番に初期化されます。その後、メイン関数でこの InitMission を呼び出すだけで済みます。
func main() { mission := InitMission("dj") mission.Start() }
依存関係注入が使用される前、コードは次のようになっていました。
func main() { monster := NewMonster() player := NewPlayer("dj") mission := NewMission(player, monster) mission.Start() }
かなり単純ではないでしょうか?ここにはオブジェクトの初期化が 3 つしかありませんが、それ以上あると、依存関係注入の利点が分からなくなる可能性があります。
例:
wire.go文件: // +build wireinject // The build tag makes sure the stub is not built in the final build. package di import ( "github.com/google/wire" ) //go:generate kratos t wire func InitApp() (*App, func(), error) { panic(wire.Build(dao.Provider, service.Provider, http.New, grpc.New, NewApp)) } 实现文件: //dao var Provider = wire.NewSet(New, NewDB, NewRedis) //service var Provider = wire.NewSet(New, wire.Bind(new(pb.Server), new(*Service))) 生成的wire_gen.go 文件: func InitApp() (*App, func(), error) { redis, cleanup, err := dao.NewRedis() if err != nil { return nil, nil, err } db, cleanup2, err := dao.NewDB() if err != nil { cleanup() return nil, nil, err } daoDao, cleanup3, err := dao.New(redis, db) if err != nil { cleanup2() cleanup() return nil, nil, err } serviceService, cleanup4, err := service.New(daoDao) if err != nil { cleanup3() cleanup2() cleanup() return nil, nil, err } engine, err := http.New(serviceService) if err != nil { cleanup4() cleanup3() cleanup2() cleanup() return nil, nil, err } server, err := grpc.New(serviceService) if err != nil { cleanup4() cleanup3() cleanup2() cleanup() return nil, nil, err } app, cleanup5, err := NewApp(serviceService, engine, server) if err != nil { cleanup4() cleanup3() cleanup2() cleanup() return nil, nil, err } return app, func() { cleanup5() cleanup4() cleanup3() cleanup2() cleanup() }, nil }
それでは、依存性注入とは正確には何でしょうか?
これは単なるカプセル化とデカップリングです。
【関連する推奨事項: Go ビデオ チュートリアル 、プログラミング教育 】
以上がGo 言語の依存性注入とは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。