はじめに
依存性注入(Dependency Injection)は、ソフトウェア開発においてコンポーネント間の依存関係を解決し、コードのテストや保守性を向上させるための重要な手法です。
Uber-Go/Digは、Go言語向けの軽量な依存性注入ライブラリであり、シンプルな実装によりコードの可読性とメンテナンス性を高めることができます。
本記事では、Uber-Go/Digの基本的な使い方と利点について解説し、サンプルコードを通じて具体的な実装方法を示します。
Uber-Go/Digとは
Uber-Go/Digは、Uberが開発したGo言語向けの依存性注入ライブラリです。
依存性注入によって、コード内で直接インスタンスを生成することなく、依存関係を明示的に定義し、それらの依存関係を注入することができます。
Uber-Go/Digは、コードをより柔軟でテストしやすい形にするだけでなく、実行時に依存関係の解決を容易にする特徴があります。
サンプルコード
まずは、依存関係を定義していきます。
package di
import (
"sam-app/internal/controller"
"sam-app/pkg/app/repository"
"sam-app/pkg/app/usecase"
"sam-app/pkg/infrastructure/database"
"go.uber.org/dig"
)
// BuildContainer はDIコンテナを構築して返します
func BuildContainer() *dig.Container {
container := dig.New()
// データベース接続関数を登録
container.Provide(database.ConnectDB)
// Controllerの実装を登録
container.Provide(controller.NewScoreController)
// Repositoryの実装を登録
container.Provide(repository.NewScoreRepository)
// // UseCaseの実装を登録
container.Provide(usecase.NewScoreUseCase)
return container
}
利用する際には、下記のような形でインスタンスを生成します。
container := di.BuildContainer()
var c *controller.ScoreController
if err := container.Invoke(func(sc *controller.ScoreController) {
c = sc
}); err != nil {
fmt.Println("Error resolving dependencies:", err)
}
綺麗なソースではありませんが、samで作成した際のサンプルを作成したので、参考にしてみてください。
まとめ
go.uber.org/digは、Go言語の依存性注入をサポートする強力なライブラリです。
リフレクションを活用し、グラフベースの依存性解決を行うことで、柔軟でテスト容易なコードを実現できます。
golangでのDIツールは他にもあり、Googleが開発しているgoogle/wire等の使用を検討することができます。