Upgrade to Pro — share decks privately, control downloads, hide ads and more …

wireのプロバイダ登録を自動化してみた

Avatar for rmocchy rmocchy
February 20, 2026
65

 wireのプロバイダ登録を自動化してみた

Go Conference mini 2026

Avatar for rmocchy

rmocchy

February 20, 2026

Transcript

  1. DI(依存性の注入)とは? オブジェクトが必要とする依存物を外部から渡すことで テストしやすい・差し替えやすいコードになる // 依存を内部で生成(密結合) func NewUserService() *UserService { db

    := NewDB() return &UserService{db: db} } // 依存を外部から注入(疎結合) func NewUserService(db *DB) *UserService { return &UserService{db: db} } Go Conference mini @mocchy 4
  2. でも規模が大きくなってくると... wire.Build( NewDB, NewLogger, NewUserRepository, NewUserService, NewAuthService, NewPostRepository, ) build

    tagのせいでIDEが一部機能せず登録が面倒(※) ぬるぽ etc... Go Conference mini @mocchy 6
  3. (A) ルート構造体の検出 ロード pkgs, err := packages.Load(cfg, "./...") names :=

    pkgs[i].Types.Scope().Names() obj := p.Types.Scope().Lookup(names[i]) 名前付き構造体以外除去 _, ok := obj.(*types.TypeName) named, ok := obj.Type().(*types.Named) namedStruct, ok := named.Underlying().(*types.Struct) Go Conference mini @mocchy 9
  4. (B) types.Func を見つける for _, fn := range fns {

    ret := fn.Signature().Results() for i := 0; i < ret.Len(); i++ { fnRetType := Deref(ret.At(i).Type()) if types.Identical(fnRetType, returnType) { result = append(result, fn) } } } ポインタはnamedではない →そのままだと取り回しが悪いので実体にしておく Go Conference mini @mocchy 10
  5. (C) types.Func から引数・pkgを取得 関数の定義先のpackageパスを取得 pkgPath := fn.Pkg() 関数の引数の型を取得 params :=

    fn.Signature().Params() for i := 0; i < params.Len(); i++ { param := params.At(i) } Go Conference mini @mocchy 11
  6. 準備 ルート構造体のみを定義 // UserApp はユーザー関係のハンドラーを持つルート構造体 type UserApp struct { UserHandler

    *handler.UserHandler } // OrderApp は注文関係のハンドラーを持つルート構造体 type OrderApp struct { ProductHandler *handler.ProductHandler OrderHandler *handler.OrderHandler } Go Conference mini @mocchy 13