Golangの依存注入の実装方法は何ですか?
Golangでの依存性注入の方法には、次のようなものがあります。
- 構造関数のインジェクション:構造体内で依存パラメータを持つ構造関数を定義し、構造体のインスタンスを作成する際に依存関係を渡す。この方法は、構造体のインスタンスを手動で作成し、依存関係を渡す必要がありますが、単体テストで仮想依存を簡単に使用できます。
type Foo struct {
Dependency *Dependency
}
func NewFoo(dependency *Dependency) *Foo {
return &Foo{
Dependency: dependency,
}
}
- 属性インジェクション:構造体内で依存性の属性を公開しておき、その構造体を使用する際に手動で依存性を設定すること。この方法は、構造体のインスタンスを作成した後に依存性を手動で設定する必要があり、ユニットテストで仮想依存性を使用するのには適していない。
type Foo struct {
Dependency *Dependency
}
func (f *Foo) SetDependency(dependency *Dependency) {
f.Dependency = dependency
}
- インターフェース注入:インターフェースを定義し、その依存メソッドをインターフェースに定義し、構造体でそのインターフェースを実装することで、使用側は具体的な構造体ではなくインターフェースに依存するようになり、実行時に依存関係を動的に置き換えることができます。この方法は、実行時に依存関係を動的に置き換える必要がある場合に適しています。
type Dependency interface {
Method()
}
type DependencyImpl struct {}
func (d *DependencyImpl) Method() {}
type Foo struct {
Dependency Dependency
}
func NewFoo(dependency Dependency) *Foo {
return &Foo{
Dependency: dependency,
}
}
- 依存性注入コンテナー:サードパーティのライブラリーまたはカスタマイズしたコンテナを使用して依存性注入を実現します。 コンテナは依存関係の作成とライフサイクルを管理し、必要な場所に依存関係を注入します。 この方法は複雑な依存関係や大規模なアプリケーションに適しています。
type DependencyImpl struct {}
func (d *DependencyImpl) Method() {}
type Foo struct {
Dependency Dependency
}
func NewFoo() *Foo {
return &Foo{}
}
func main() {
container := di.NewContainer()
container.Register(&DependencyImpl{})
container.Register(func(dependency Dependency) *Foo {
return &Foo{
Dependency: dependency,
}
})
foo := container.Resolve((*Foo)(nil)).(*Foo)
}
具体のアプリケーションシナリオや要件に応じて、いくつかの一般的な依存性注入方法があります。適切な方法を選択することができます。