golang-google-wire
Go言語でコンパイル時依存性注入を行う`google/wire`の利用を支援するスキルです。`wire.NewSet`・`wire.Build`・`wire.Bind`・`wire.Struct`・`wire.Value`・`wire.FieldsOf`やクリーンアップ関数、`//go:build wireinject`アノテーション、生成される`wire_gen.go`まで幅広くカバーします。`github.com/google/wire`をインポートしている場合や、`wire.Build`でアプリケーションの依存グラフをコンパイル時に構築する際に適用されます。リフレクションを使ったランタイムDIには`golang-uber-dig`スキルを参照してください。
description の原文を見る
Compile-time dependency injection in Golang using google/wire — wire.NewSet, wire.Build, wire.Bind (interface→concrete), wire.Struct, wire.Value, wire.InterfaceValue, wire.FieldsOf, cleanup functions, //go:build wireinject injector files, and generated wire_gen.go. Apply when using or adopting google/wire, when the codebase imports `github.com/google/wire`, or when wiring an application graph at compile time via `wire.Build`. For runtime DI with reflection, see `samber/cc-skills-golang@golang-uber-dig` skill.
SKILL.md 本文
ペルソナ: あなたは wire を使ってコンパイル時 DI を実行する Go アーキテクトです。コンパイラに依存関係の不足を検出させ、wire_gen.go をコミット対象のソースとして扱い、グラフの変更があるたびに wire ./... を再実行します。
Go で google/wire を使用したコンパイル時依存性注入
コード生成型 DI ツールキット。Wire は依存グラフをコンパイル時に解決し、平素な Go のコンストラクタ呼び出しを生成します。ランタイムコンテナも、リフレクションも不要です。エラーは最初のリクエスト時ではなく、wire ./... を実行したときに出現します。
注記: google/wire は 2025 年 8 月にアーカイブされました (機能は完全; バグ修正は引き続き受け付けます)。
公式リソース: pkg.go.dev · github.com/google/wire · User Guide · Best Practices
このスキルは網羅的ではありません。詳しい情報についてはライブラリドキュメントとコード例を参照してください。Context7 は発見プラットフォームとして役立ちます。
go install github.com/google/wire/cmd/wire@latest
go get github.com/google/wire
wire vs. ランタイム DI
| 項目 | wire | dig / fx / samber/do |
|---|---|---|
| 解決タイミング | コンパイル時 (コード生成) | ランタイム (リフレクション) |
| エラー検出 | wire ./... がフェイル | 最初の Invoke/起動時 |
| ランタイムコンテナ | なし — 平素な Go 呼び出し | あり |
| ライフサイクルフック | 組み込みなし | fx: OnStart/OnStop |
| 生成ファイル | wire_gen.go (コミット済み) | なし |
ライフサイクル、遅延ロード、および完全な比較表については samber/cc-skills-golang@golang-dependency-injection を参照してください。
プロバイダー
プロバイダーは任意の Go 関数です。入力値は依存関係、出力値は提供される型です。3 つの戻り値の形式があります:
func NewConfig() *Config { return &Config{Addr: ":8080"} }
func NewDB(cfg *Config) (*sql.DB, error) { return sql.Open("postgres", cfg.DSN) }
func NewRedis(cfg *Config) (*redis.Client, func(), error) { // cleanup は逆順でチェーンされる
c := redis.NewClient(&redis.Options{Addr: cfg.RedisAddr})
return c, func() { c.Close() }, nil
}
プロバイダーセット
wire.NewSet はプロバイダーを再利用のためにグループ化します。セットは他のセットを参照できます。
// infra/wire.go
var InfraSet = wire.NewSet(
NewConfig,
NewDB,
NewRedis,
)
// service/wire.go
var ServiceSet = wire.NewSet(
NewUserRepo,
NewUserService,
wire.Bind(new(UserStore), new(*UserRepo)), // インターフェースバインディング
)
セットは小さく保ちます。ライブラリセットは安定したサーフェスを公開します (入力を追加したり出力を削除したりすると、下流のインジェクターが壊れます)。パッケージあたり 1 つのセットが有用なデフォルトです。
インジェクターと //go:build wireinject
インジェクターファイルは初期化関数を宣言します。Wire はその本体を wire_gen.go に生成し、スタブを置き換えます。
//go:build wireinject
package main
import "github.com/google/wire"
// Wire がこの関数の本体を生成します。
func InitApp() (*App, func(), error) {
wire.Build(InfraSet, ServiceSet, NewApp)
return nil, nil, nil // コード生成で置き換える
}
//go:build wireinject タグはスタブがバイナリにコンパイルされるのを防ぎます。wire_gen.go (このタグを持たない) だけが go build を通ります。このタグを省略すると、両方のファイルが同じ関数を定義するため、コンパイルエラーが発生します。
ダミーの戻り値が不便な場合の代替構文:
func InitApp() (*App, func(), error) {
panic(wire.Build(InfraSet, ServiceSet, NewApp))
}
インターフェースバインディング
Wire は暗黙的なインターフェース満足を禁止します。グラフが複数の型が同じインターフェースを実装する場合に曖昧さのないよう、バインディングを明示的に宣言する必要があります。
var Set = wire.NewSet(
NewPostgresUserRepo,
wire.Bind(new(UserStore), new(*PostgresUserRepo)), // Wire に伝える: *PostgresUserRepo は UserStore を満足する
)
明示的なバインディングにより、同じインターフェースを実装する新しい型が別の場所に追加される場合のグラフ破壊を防ぎます。
構造体プロバイダーと値
wire.Struct は手動のコンストラクタなしでグラフから構造体フィールドを埋めます。wire:"-" タグで除外するフィールドをマークします。
wire.Struct(new(Server), "Logger", "DB") // 指定されたフィールドを注入
wire.Struct(new(Server), "*") // 除外されないすべてのフィールドを注入
wire.Value(Foo{X: 42}) // 定数式 (関数呼び出し/チャネルなし)
wire.InterfaceValue(new(io.Reader), os.Stdin) // インターフェース型リテラル
wire.FieldsOf(new(Config), "DSN", "Addr") // 構造体フィールドをグラフノードとして昇格
wire:"-" 除外タグと wire.FieldsOf の詳細については advanced.md を参照してください。
重複型の曖昧さ解消
Wire は同じ型に対する 2 つのプロバイダーを禁止します。基になる型を異なる名前付き型でラップして、それぞれが正確に 1 つのプロバイダーを持つようにします:
type PrimaryDSN string
type ReplicaDSN string
完全なアプリケーション例
// wire.go — インジェクター、ビルドタグによってバイナリから除外
//go:build wireinject
package main
func InitApp() (*App, func(), error) {
wire.Build(config.ConfigSet, infra.InfraSet, service.ServiceSet, NewApp)
return nil, nil, nil
}
// main.go
func main() {
app, cleanup, err := InitApp()
if err != nil { log.Fatal(err) }
defer cleanup()
app.Run()
}
Wire は wire_gen.go (平素な Go、コミット済み、編集不可) を生成します。パッケージごとのセット、cleanup が重いグラフ、生成されたファイルを含む完全な例については recipes.md を参照してください。
コード生成ワークフロー
wire ./... # モジュール内のすべてのインジェクターを再生成
wire check ./... # グラフを検証して再生成しない (高速な CI チェック)
コンストラクタシグネチャを変更するたびに wire ./... を実行します。go generate ./... も機能するよう、インジェクターファイルに //go:generate go run github.com/google/wire/cmd/wire を追加します。wire_gen.go をコミットします。CI ビルドと同期していなければなりません。
ベストプラクティス
wire_gen.goは決して編集しないでください。wire ./...実行するたびに上書きされます。これはコミットされるビルド成果物として扱い、ソースオブトゥルースはプロバイダーとインジェクターファイルです。- インジェクターファイルに
//go:build wireinjectを常に追加してください。省略すると、スタブと生成ファイル双方が同じ関数を定義するため、重複シンボルコンパイルエラーが発生します。 - 同じ基になる型の値を区別する名前付き型を使用してください。Wire は型あたり 1 つのプロバイダーを強制します。
type DSN stringのような名前付き型により、PrimaryDSNとReplicaDSNは共存できます。 - ライブラリプロバイダーセットを最小限で後方互換的に保ちます。新しい必須入力を追加すると、下流のインジェクターが壊れます。出力を削除することもです。同じリリースでは新たに作成された型のみを導入します。
- cleanup プロバイダーから
(T, func(), error)を返し、Wire にチェーンさせます。Wire は正しい逆順のクリーンアップを生成し、部分的な失敗を処理します (構築が途中で失敗した場合、既に構築されたクリーンアップのみ実行されます)。 - インジェクターファイルに焦点を当てます。ファイルあたり 1 つの関数、一度に 1 つのパッケージインポート。数十の
wire.Build引数を持つ巨大なインジェクターは推論が困難です。パッケージごとのセットに委譲します。
一般的な間違い
| 間違い | 修正 |
|---|---|
wire_gen.go の手動編集 | 決して編集しないでください。プロバイダーまたはインジェクターを変更して wire ./... を再実行します。 |
//go:build wireinject が不足 | すべてのインジェクターファイルの最初の行として、タグを追加します。 |
*sql.DB を返す 2 つのプロバイダー | 名前付き型でラップします (type PrimaryDB *sql.DB またはラッパー構造体)。 |
wire.Bind なしでインターフェースを注入 | プロバイダーセットに wire.Bind(new(MyInterface), new(*MyImpl)) を追加します。 |
変更後 wire ./... の再実行を忘れ | go build 前に wire を実行します。go generate または Makefile ターゲットに追加します。 |
cleanup() を nil ガードなしで呼び出す | Wire は構築エラー時に nil クリーンアップを返します。if cleanup != nil { defer cleanup() } でガードします。 |
テスト
Wire は平素な Go コンストラクタを生成するため、単体テストは手動注入を使用します。コンテナをクローンまたはリセットする必要はありません。テストパターン (実プロバイダーをフェイクでスワップするテストインジェクター、wire_gen.go の CI stale チェック) については testing.md を参照してください。
参考文献
advanced.md— cleanup チェーン、複数インジェクター、セットネスト、エラーカタログ、コード生成フラグ、クイックリファレンスrecipes.md— HTTP サーバー、マルチインジェクタービルド、cleanup が重いグラフ、CLI 埋め込みtesting.md— テストインジェクター、フェイクバインディング、CI stale チェック
クロスリファレンス
- → DI の概念とライブラリ比較については
samber/cc-skills-golang@golang-dependency-injectionスキルを参照 - → ランタイムリフレクションベースの DI でライフサイクルなしについては
samber/cc-skills-golang@golang-uber-digスキルを参照 - → ランタイム DI、ライフサイクルフック、モジュール、シグナル対応 Run() については
samber/cc-skills-golang@golang-uber-fxスキルを参照 - → リフレクションなしのジェネリクスベース DI については
samber/cc-skills-golang@golang-samber-doスキルを参照 - → インターフェースデザインパターンについては
samber/cc-skills-golang@golang-structs-interfacesスキルを参照 - → 一般的なテストパターンについては
samber/cc-skills-golang@golang-testingスキルを参照
google/wire でバグまたは予期しない動作に遭遇した場合は、https://github.com/google/wire/issues で issue を開いてください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- samber
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/samber/cc-skills-golang / ライセンス: MIT
関連スキル
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
civ-finish-quotes
実質的なタスクが真に完了した際に、文明風の儀式的な引用句を追加します。ユーザーやエージェントが機能追加、リファクタリング、分析、設計ドキュメント、プロセス改善、レポート、執筆タスクといった実際の成果物を完成させるときに、明示的な依頼がなくても使用します。短い返信や小さな修正、未完成の作業には適用しません。
nookplot
Base(Ethereum L2)上のAIエージェント向け分散型調整ネットワークです。エージェントがオンチェーンアイデンティティを登録する、コンテンツを公開する、他のエージェントにメッセージを送る、マーケットプレイスで専門家を雇う、バウンティを投稿・請求する、レピュテーションを構築する、共有プロジェクトで協業する、リサーチチャレンジを解くことでNOOKをマイニングする、キュレーションされたナレッジを備えたスタンドアロンオンチェーンエージェントをデプロイする、またはアグリーメントとリワードで収益を得る場合に利用できます。エージェントネットワーク、エージェント調整、分散型エージェント、NOOKトークン、マイニングチャレンジ、ナレッジバンドル、エージェントレピュテーション、エージェントマーケットプレイス、ERC-2771メタトランザクション、Prepare-Sign-Relay、AgentFactory、またはNookplotが言及された場合にトリガーされます。
web3-polymarket
Polygon上でのPolymarket予測市場取引統合です。認証機能(L1 EIP-712、L2 HMAC-SHA256、ビルダーヘッダー)、注文発注(GTC/GTD/FOK/FAK、バッチ、ポストオンリー、ハートビート)、市場データ(Gamma API、Data API、オーダーブック、サブグラフ)、WebSocketストリーミング(市場・ユーザー・スポーツチャネル)、CTF操作(分割、統合、償却、ネガティブリスク)、ブリッジ機能(入金、出金、マルチチェーン)、およびガスレスリレイトランザクションに対応しています。AIエージェント、自動マーケットメーカー、予測市場UI、またはPolygraph上のPolymarketと統合するアプリケーション構築時に活用できます。
ethskills
Ethereum、EVM、またはブロックチェーン関連のリクエストに対応します。スマートコントラクト、dApps、ウォレット、DeFiプロトコルの構築、監査、デプロイ、インタラクションに適用されます。Solidityの開発、コントラクトアドレス、トークン規格(ERC-20、ERC-721、ERC-4626など)、Layer 2ネットワーク(Base、Arbitrum、Optimism、zkSync、Polygon)、Uniswap、Aave、Curveなどのプロトコルとの統合をカバーします。ガスコスト、コントラクトのデシマル設定、オラクルセキュリティ、リエントランシー、MEV、ブリッジング、ウォレット管理、オンチェーンデータの取得、本番環境へのデプロイ、プロトコル進化(EIPライフサイクル、フォーク追跡、今後の変更予定)といったトピックを含みます。
xxyy-trade
このスキルは、ユーザーが「トークン購入」「トークン売却」「トークンスワップ」「暗号資産取引」「取引ステータス確認」「トランザクション照会」「トークンスキャン」「フィード」「チェーン監視」「トークン照会」「トークン詳細」「トークン安全性確認」「ウォレット一覧表示」「マイウォレット」「AIスキャン」「自動スキャン」「ツイートスキャン」「オンボーディング」「IP確認」「IPホワイトリスト」「トークン発行」「自動売却」「損切り」「利益確定」「トレーリングストップ」「保有者」「トップホルダー」「KOLホルダー」などをリクエストした場合、またはSolana/ETH/BSC/BaseチェーンでXXYYを経由した取引について言及した場合に使用します。XXYY Open APIを通じてオンチェーン取引とデータ照会を実現します。