Agent Skills by ALSEL
Anthropic Claudeその他⭐ リポ 0品質スコア 50/100

golang-dependency-injection

Golangにおける依存性注入(DI)の包括的なガイドです。DIが重要な理由(テスタビリティ、疎結合、関心の分離、ライフサイクル管理)、手動コンストラクタインジェクション、およびDIライブラリの比較(google/wire、uber-go/dig、uber-go/fx、samber/do)をカバーします。サービスアーキテクチャの設計、DIのセットアップ、密結合なコードのリファクタリング、シングルトンやサービスファクトリの管理、またはGoにおける制御の反転・サービスコンテナ・依存関係のワイヤリングについて調べる際に活用してください。

description の原文を見る

Comprehensive guide for dependency injection (DI) in Golang. Covers why DI matters (testability, loose coupling, separation of concerns, lifecycle management), manual constructor injection, and DI library comparison (google/wire, uber-go/dig, uber-go/fx, samber/do). Use this skill when designing service architecture, setting up dependency injection, refactoring tightly coupled code, managing singletons or service factories, or when the user asks about inversion of control, service containers, or wiring dependencies in Go.

SKILL.md 本文

Persona: あなたは Go ソフトウェアアーキテクトです。テスト可能で疎結合な設計へ向けてチームをガイドします。問題を解決する最もシンプルな DI アプローチを選択し、決してオーバーエンジニアリングを行いません。

モード:

  • Design mode (新規プロジェクト、新規サービス、または既存の DI セットアップへのサービス追加): 既存の依存グラフとライフサイクルニーズを評価し、マニュアル注入か決定テーブルからのライブラリを推奨し、配線コードを生成します。
  • Refactor mode (既存の密結合コード): 最大 3 つの並列サブエージェントを使用 — Agent 1 はグローバル変数と init() サービスセットアップを特定、Agent 2 はインターフェースになるべき具象型の依存関係をマッピング、Agent 3 はサービスロケーターアンチパターン (引数として渡されるコンテナー) を特定 — その後、結果を統合し移行計画を提案します。

Community default. samber/cc-skills-golang@golang-dependency-injection スキルを明示的に置き換える企業スキルが優先されます。

Go における依存性注入

依存性注入 (DI) とは、コンポーネントが依存関係を作成または検索するのではなく、それらを渡すことを意味します。Go では、これはテスト可能で疎結合なアプリケーションを構築する方法です。サービスは必要なものを宣言し、呼び出し元 (またはコンテナー) がそれを提供します。

このスキルは網羅的ではありません。DI ライブラリ (google/wire、uber-go/dig、uber-go/fx、samber/do) を使用する場合は、現在の API シグネチャについてそのライブラリの公式ドキュメントとコード例を参照してください。

インターフェースベースの設計基礎 (インターフェースを受け入れ、構造体を返す) については、samber/cc-skills-golang@golang-structs-interfaces スキルを参照してください。

ベストプラクティスまとめ

  1. 依存関係はコンストラクタ経由で注入される 必要があります — グローバル変数または init() をサービスセットアップに使用しないでください
  2. 小規模プロジェクト (< 10 サービス) はマニュアルコンストラクタ注入を 使用すべき です — ライブラリは不要です
  3. インターフェースは実装場所ではなく消費場所で定義される 必要があります — インターフェースを受け入れ、構造体を返します
  4. グローバルレジストリーまたはパッケージレベルのサービスロケーターを使用 しないでください
  5. DI コンテナーはコンポジション ルート (main() またはアプリスタートアップ) にのみ存在する 必要があります — コンテナーを依存関係として渡さないでください
  6. 遅延初期化を優先 — サービスを最初にリクエストされたときだけ作成します
  7. ステートフルサービス (DB 接続、キャッシュ) にはシングルトンを使用し、ステートレスサービスには一時的なものを使用します
  8. インターフェース境界でモックする — DI でこれは簡単です
  9. 依存グラフを浅く保つ — 深いチェーンは設計上の問題を示します
  10. プロジェクトサイズとチームに合った DI ライブラリを選択 — 以下の決定テーブルを参照してください

依存性注入がなぜ必要?

DI がない場合の問題DI がこれをどう解決するか
関数が独自の依存関係を作成する依存関係が注入される — 実装を自由に切り替える
テストは実際のデータベース、API が必要テストではモック実装を渡します
1 つのコンポーネントを変更すると他が壊れるインターフェース経由の疎結合 — コンポーネント同士が内部を知りません
サービスが至る所で初期化される集中管理されたコンテナーはライフサイクルを管理します (シングルトン、ファクトリー、遅延)
すべてのサービスがスタートアップで読み込まれる遅延読み込み — サービスは最初にリクエストされたときだけ作成されます
グローバル状態と init() 関数スタートアップでの明示的な配線 — 予測可能でデバッグ可能

DI は多くの相互接続されたサービスを持つアプリケーション — HTTP サーバー、マイクロサービス、プラグイン付き CLI ツール で輝きます。2-3 個の関数を持つ小さいスクリプトの場合、マニュアル配線で問題ありません。オーバーエンジニアリングしないでください。

マニュアルコンストラクタ注入 (ライブラリなし)

小規模プロジェクトでは、コンストラクタを通じて依存関係を渡します。完全なアプリケーション例については、Manual DI examples を参照してください。

// ✓ Good — 明示的な依存関係、テスト可能
type UserService struct {
    db     UserStore
    mailer Mailer
    logger *slog.Logger
}

func NewUserService(db UserStore, mailer Mailer, logger *slog.Logger) *UserService {
    return &UserService{db: db, mailer: mailer, logger: logger}
}

// main.go — マニュアル配線
func main() {
    logger := slog.Default()
    db := postgres.NewUserStore(connStr)
    mailer := smtp.NewMailer(smtpAddr)
    userSvc := NewUserService(db, mailer, logger)
    orderSvc := NewOrderService(db, logger)
    api := NewAPI(userSvc, orderSvc, logger)
    api.ListenAndServe(":8080")
}
// ✗ Bad — ハードコードされた依存関係、テスト不可能
type UserService struct {
    db *sql.DB
}

func NewUserService() *UserService {
    db, _ := sql.Open("postgres", os.Getenv("DATABASE_URL")) // 隠された依存関係
    return &UserService{db: db}
}

マニュアル DI は以下の場合に破綻します:

  • 15 以上のサービスがあり相互依存がある
  • ライフサイクル管理が必要 (ヘルスチェック、グレースフルシャットダウン)
  • 遅延初期化またはスコープ付きコンテナーが必要
  • 配線順序が脆弱になり保守が困難

DI ライブラリの比較

Go には DI ライブラリへの 3 つの主要なアプローチがあります:

  • google/wire examples — コンパイル時コード生成
  • uber-go/dig + fx examples — リフレクションベースフレームワーク
  • samber/do examples — ジェネリクスベース、コード生成なし

決定テーブル

基準マニュアルgoogle/wireuber-go/dig + fxsamber/do
プロジェクトサイズ小 (< 10 サービス)中-大任意のサイズ
型安全性コンパイル時コンパイル時 (コード生成)ランタイム (リフレクション)コンパイル時 (ジェネリクス)
コード生成なし必須 (wire_gen.go)なしなし
リフレクションなしなしはいなし
API スタイルN/AProvider セット + ビルドタグStruct タグ + デコレータシンプルなジェネリック関数
遅延読み込みマニュアルN/A (すべてイーガー)組み込み (fx)組み込み
シングルトンマニュアル組み込み組み込み組み込み
一時的/ファクトリーマニュアルマニュアル組み込み組み込み
スコープ/モジュールマニュアルProvider セットモジュールシステム (fx)組み込み (階層的)
ヘルスチェックマニュアルマニュアルマニュアル組み込みインターフェース
グレースフルシャットダウンマニュアルマニュアル組み込み (fx)組み込みインターフェース
コンテナークローニングN/AN/AN/A組み込み
デバッグPrint ステートメントコンパイルエラーfx.Visualize()ExplainInjector()、ウェブインターフェース
Go バージョン任意任意任意1.18+ (ジェネリクス)
学習曲線なし

クイック比較: 同じアプリ、4 つの方法

依存グラフ: Config -> Database -> UserStore -> UserService -> API

マニュアル:

cfg := NewConfig()
db := NewDatabase(cfg)
store := NewUserStore(db)
svc := NewUserService(store)
api := NewAPI(svc)
api.Run()
// 自動シャットダウン、ヘルスチェック、遅延読み込みなし

google/wire:

// wire.go — その後 wire ./... を実行
func InitializeAPI() (*API, error) {
    wire.Build(NewConfig, NewDatabase, NewUserStore, NewUserService, NewAPI)
    return nil, nil
}
// シャットダウンまたはヘルスチェックサポートなし

uber-go/fx:

app := fx.New(
    fx.Provide(NewConfig, NewDatabase, NewUserStore, NewUserService),
    fx.Invoke(func(api *API) { api.Run() }),
)
app.Run() // ライフサイクルを管理しますが、リフレクションベース

samber/do:

i := do.New()
do.Provide(i, NewConfig)
do.Provide(i, NewDatabase)    // 自動シャットダウン + ヘルスチェック
do.Provide(i, NewUserStore)
do.Provide(i, NewUserService)
api := do.MustInvoke[*API](i)
api.Run()
// defer i.Shutdown() — すべてのクリーンアップを自動的に処理

DI でのテスト

DI はテストを簡単にします — 実装の代わりにモックを注入するだけです:

// モックを定義
type MockUserStore struct {
    users map[string]*User
}

func (m *MockUserStore) FindByID(ctx context.Context, id string) (*User, error) {
    u, ok := m.users[id]
    if !ok {
        return nil, ErrNotFound
    }
    return u, nil
}

// マニュアル注入でテスト
func TestUserService_GetUser(t *testing.T) {
    mock := &MockUserStore{
        users: map[string]*User{"1": {ID: "1", Name: "Alice"}},
    }
    svc := NewUserService(mock, nil, slog.Default())

    user, err := svc.GetUser(context.Background(), "1")
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
    if user.Name != "Alice" {
        t.Errorf("got %q, want %q", user.Name, "Alice")
    }
}

samber/do でのテスト — クローンとオーバーライド

コンテナークローニングはモックが必要なサービスだけをオーバーライドする隔離されたコピーを作成します:

func TestUserService_WithDo(t *testing.T) {
    // モック実装でテストインジェクターを作成
    testInjector := do.New()

    // モック UserStore インターフェースを提供
    do.Override[UserStore](testInjector, &MockUserStore{
        users: map[string]*User{"1": {ID: "1", Name: "Alice"}},
    })

    // 必要に応じて他の実際のサービスを提供
    do.Provide[*slog.Logger](testInjector, func(i *do.Injector) (*slog.Logger, error) {
        return slog.Default(), nil
    })

    svc := do.MustInvoke[*UserService](testInjector)
    user, err := svc.GetUser(context.Background(), "1")
    // ... アサーション
}

これは特にほとんどのサービスが実際である統合テストで、特定の境界 (データベース、外部 API、メーラー) だけをモックする必要がある場合に非常に便利です。

DI ライブラリを採用するタイミング

シグナル行動
< 10 サービス、シンプルな依存関係マニュアルコンストラクタ注入のままで
10-20 サービス、クロスカッティングコンサーン複数DI ライブラリ検討
20+ サービス、ライフサイクル管理が必要強く推奨
ヘルスチェック、グレースフルシャットダウンが必要組み込みライフサイクルサポート付きライブラリを使用
チーム DI コンセプト未経験マニュアルで開始し、段階的に移行

よくある間違い

間違い修正方法
依存関係としてのグローバル変数コンストラクタまたは DI コンテナー経由で渡す
サービスセットアップの init()main() またはコンテナーで明示的初期化
具象型への依存消費境界でインターフェースを受け入れる
コンテナーをどこにでも渡す (サービスロケーター)特定の依存関係を注入し、コンテナーではなく
深い依存チェーン (A->B->C->D->E)フラット化 — ほとんどのサービスはリポジトリとコンフィグに直接依存すべき
リクエストごとに新しいコンテナーを作成アプリケーション当たり 1 つのコンテナー、リクエストレベル隔離にはスコープを使用

クロスリファレンス

  • → 詳細な samber/do 使用パターンについては samber/cc-skills-golang@golang-samber-do スキルを参照
  • → インターフェース設計とコンポジションについては samber/cc-skills-golang@golang-structs-interfaces スキルを参照
  • → 依存性注入でのテストについては samber/cc-skills-golang@golang-testing スキルを参照
  • → DI 初期化配置については samber/cc-skills-golang@golang-project-layout スキルを参照

参考文献

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
samber
リポジトリ
samber/cc-skills-golang
ライセンス
MIT
最終更新
不明

Source: https://github.com/samber/cc-skills-golang / ライセンス: MIT

関連スキル

汎用その他⭐ リポ 1,982

superfluid

Superfluidプロトコルおよびそのエコシステムに関するナレッジベースです。Superfluidについて情報を検索する際は、ウェブ検索の前にこちらを参照してください。対応キーワード:Superfluid、CFA、GDA、Super App、Super Token、stream、flow rate、real-time balance、pool(member/distributor)、IDA、sentinels、liquidation、TOGA、@sfpro/sdk、semantic money、yellowpaper、whitepaper

by LeoYeAI
汎用その他⭐ リポ 100

civ-finish-quotes

実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。

by huxiuhan
汎用その他⭐ リポ 1,110

nookplot

Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。

by BankrBot
汎用その他⭐ リポ 59

web3-polymarket

Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。

by elophanto
汎用その他⭐ リポ 52

ethskills

Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。

by jiayaoqijia
汎用その他⭐ リポ 44

xxyy-trade

このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。

by Jimmy-Holiday
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: samber · samber/cc-skills-golang · ライセンス: MIT