> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gocopper.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Dependency Injection

Copper uses [google/wire](https://github.com/google/wire) for dependency injection. Wire generates plain Go code at build time, so there is no runtime container and no reflection. If your dependency graph has a problem, you will find out with a compile error rather than a production surprise.

You will rarely write wire code by hand. `copper scaffold:pkg`, `scaffold:router`, and `scaffold:queries` maintain it for you, and `copper run` regenerates it on every build.

### Wire Modules

Each package declares what it provides in a `wire.go` file:

```go pkg/rockets/wire.go theme={null}
var WireModule = wire.NewSet(
	LoadConfig,
	wire.Struct(new(NewSvcParams), "*"),
	NewSvc,
	wire.Struct(new(NewRouterParams), "*"),
	NewRouter,
)
```

The `wire.Struct(new(NewSvcParams), "*")` line tells wire to fill every field of the params struct from the dependency graph. This **params struct convention** is used throughout Copper:

```go theme={null}
type NewSvcParams struct {
	Queries *Queries
	Mission *missions.Svc
	Logger  clogger.Logger
}

func NewSvc(p NewSvcParams) *Svc {
	return &Svc{queries: p.Queries, mission: p.Mission, logger: p.Logger}
}
```

Adding a dependency is a one-line struct change. You will not need to update constructor signatures throughout your codebase, or edit any wire code beyond the package's own module.

### Composing Modules

`pkg/app/wire.go` is the composition root for your packages. `copper scaffold:pkg` adds each new package's module to it, alongside a few app-level providers:

```go pkg/app/wire.go theme={null}
var WireModule = wire.NewSet(
	MetricsRegistry,
	ProvideLoggerHooks,

	rockets.WireModule,
	missions.WireModule,
)
```

Copper ships several wire modules that you may pull into your binaries as needed:

| Module                      | Provides                                                                                             |
| --------------------------- | ---------------------------------------------------------------------------------------------------- |
| `copper.WireModule`         | `cconfig.Loader`, `*clifecycle.Lifecycle`, `clogger.Logger`                                          |
| `chttp.WireModule`          | HTTP server, JSON/HTML reader-writers, request logger middleware                                     |
| `chttp.WireModuleEmptyHTML` | Empty HTML/static dir values to satisfy `chttp.WireModule` in API-only apps with no `web/` directory |
| `csql.WireModule`           | DB connection, `csql.Querier`, migrator, transaction middleware                                      |
| `cmetrics.WireModule`       | `cmetrics.Metrics` (you provide the `*Registry`)                                                     |

### Binding Interfaces

If you would like to depend on an interface rather than a concrete type, add a `wire.Bind`:

```go theme={null}
var WireModule = wire.NewSet(
	wire.Struct(new(NewSvcParams), "*"),
	NewSvc,
	wire.Bind(new(Telemetry), new(*SatelliteTelemetry)),
)
```

Any package may now ask for `Telemetry` and receive the satellite implementation. If you decide to swap implementations later, it is a one-line change.

### Regenerating

Wire output is generated into `wire_gen.go` files, which are checked in. `copper run` and `copper build` regenerate them automatically. If you would like to run the generator manually:

```
go run github.com/google/wire/cmd/wire ./...
```

<Note>
  Wire errors can look intimidating, but they almost always say one of two things: a type has **no provider** (a constructor or module is missing from a wire set) or has **two providers** (the same type is provided in two modules). Read the first error, find the type it names, and check your `WireModule`s for it.
</Note>
