# google/wire — Compile-Time Code Generation

Wire uses code generation to resolve the dependency graph at compile time. Type-safe, but requires a build step.

- Docs: [github.com/google/wire](https://github.com/google/wire) | [User Guide](https://github.com/google/wire/blob/main/docs/guide.md)

Before writing Wire code, refer to the library's official documentation for up-to-date API signatures and examples.

## Provider Definitions

```go
// providers.go
package wire

import "github.com/google/wire"

// ProviderSet groups related providers
var InfraSet = wire.NewSet(
    NewConfig,
    NewDatabase,
    NewCache,
)

var ServiceSet = wire.NewSet(
    NewUserService,
    wire.Bind(new(UserStore), new(*PostgresUserStore)), // bind interface to impl
)
```

## Injector Definition

```go
// wire.go — build constraint ensures this is only used by the wire tool
//go:build wireinject

package main

import "github.com/google/wire"

func InitializeApp() (*App, error) {
    wire.Build(
        InfraSet,
        ServiceSet,
        NewApp,
    )
    return nil, nil // wire replaces this body
}
```

## Generated Code

Run `wire ./...` to produce `wire_gen.go`:

```go
// wire_gen.go — DO NOT EDIT (auto-generated by wire)
func InitializeApp() (*App, error) {
    config := NewConfig()
    database, err := NewDatabase(config)
    if err != nil {
        return nil, err
    }
    cache := NewCache(config)
    store := NewPostgresUserStore(database)
    userService := NewUserService(store, cache)
    app := NewApp(userService)
    return app, nil
}
```

## Testing

Wire generates plain constructors, so testing uses manual injection — no container to clone:

```go
func TestUserService(t *testing.T) {
    mock := &MockUserStore{...}
    svc := NewUserService(mock, NewTestCache())
    // ... test
}
```

## Tradeoffs

- Errors caught at compile time (codegen fails if graph is incomplete)
- Requires running `wire ./...` after every dependency change
- No lazy loading — all dependencies created eagerly
- No built-in lifecycle management (health checks, shutdown)
- No runtime container — wire generates plain Go constructor calls
- Interface bindings require explicit `wire.Bind` declarations
- Generated files (`wire_gen.go`) must be committed and kept in sync

Wire injectors MUST use `//go:build wireinject` build constraint. Generated `wire_gen.go` MUST NOT be edited manually — always regenerate with `wire ./...`.
