# GenDI > GenDI — Generated Dependency Injection. A compile-time DI container generator for Go, configured in YAML. Short, stable facts about GenDI for tooling and assistants. The same text is served at `https://gendi.dev/llms.txt`, so an agent can read it in one fetch instead of crawling this documentation. The project is `GenDI`; the module, the command and the config file are all lowercase `gendi`. ## Schema `gendi.schema.json` in the repository root is the machine-readable contract for a config file — validate a generated config against it before running the generator. A test keeps it in step with the loader, so what it rejects, the loader rejects. Editors get the same checking from a first line of: ```yaml # yaml-language-server: $schema=https://raw.githubusercontent.com/gendi-org/gendi/master/gendi.schema.json ``` Anything the schema accepts can still fail generation for reasons it cannot see — unknown service IDs, type mismatches against the real Go signatures, dependency cycles. Those are reported with the offending line and a caret. ## CLI ```bash go get -tool github.com/gendi-org/gendi/cmd/gendi # once, per module go tool gendi --config=gendi.yaml --out=./di --pkg=di ``` Flags: `--config`, `--out`, `--pkg`, `--container`, `--build-tags`, `--enable-pass`, `--verbose`. ## YAML Syntax Constructor args: - `@service.id` service reference - `@.inner` inner service (decorators only) - `%param.name%` parameter - `!tagged:tag.name` tagged injection - `!spread:@service` spread slice into variadic - `!spread:!tagged:tag` spread tagged collection into variadic - `!go:pkg.Symbol` Go package-level var/const (e.g. `!go:os.Stdout`) - `!field:@service.Field` field access on service (e.g. `!field:@config.Host`) - `!field:!go:pkg.Symbol.Field` field access on Go symbol (e.g. `!field:!go:http.DefaultClient.Timeout`) - literal scalars (string/int/float/bool/null) Method constructors are configured via the `constructor.method` field (`method: "@factory.Create"`), not as a constructor argument. `$this.` in `type` and `func` fields, a tag's `element_type`, `!go:` arguments, and `!field:!go:` arguments resolves to the Go package path of the config file. The `method` field takes no `$this` — it addresses a service, not a package. Imports support `exclude`: ```yaml imports: - path: ./services/*.yaml exclude: - ./services/test_*.yaml ``` ## Service Defaults `services._default` sets the default `shared`, `public`, and `autoconfigure` flags for the services of the same file (per file; not inherited across imports). Any other field in `_default` is an error. Built-in defaults: `shared: true`, `public: false`, `autoconfigure: true`. ## Parameters Declared as plain scalar defaults (no `type` field; null and mapping values rejected): ```yaml parameters: port: 8080 timeout: 5s ``` The target type is contextual — taken from each constructor argument. One parameter may be injected as different types at different sites. Supported targets: `string`, `bool`, all int/uint widths, `float32`, `float64`, `time.Duration`, `time.Time`, and named types over those (static conversion is generated). `uintptr` unsupported. Runtime split: `Provider.Lookup(name) (any, error)` returns the raw value; `parameters.Caster` (`StandardCaster` by default, override via `WithParameterCaster`) converts it per injection site. Generated code calls both through the `parameters.Resolver` facade struct: `c.paramsResolver.Int("port")`. Unsupported targets and non-convertible defaults fail at generation time; runtime provider values are checked at construction with parameter name, service ID, argument index, raw and target types in the error. ## Spread Rules - Only one `!spread:` per constructor call - Must be the last argument - Inner expression must resolve to a slice - Target parameter must be variadic ## Pruning Public services (and public tags) are the generation roots. Services unreachable from a root are dropped after validation, together with the parameters only they injected. `--enable-pass=expose-all` makes everything public and disables pruning. ## Generated Container API ```go var DefaultContainerParameters *parameters.ProviderMap // injected YAML defaults; omitted when none survive pruning func NewContainer(params parameters.Provider, opts ...ContainerOption) *Container func (c *Container) GetServiceName() (ServiceType, error) func (c *Container) MustServiceName() ServiceType func WithContainerErrorHandler(handler func(serviceName string, err error)) ContainerOption func WithContainerParameterCaster(caster parameters.Caster) ContainerOption ``` `NewContainer(nil)` uses `DefaultContainerParameters`, or `parameters.ProviderNullInstance` when it is absent. Parameters no surviving service injects are pruned from the defaults after unreachable services are pruned; the variable is emitted only when at least one remains. Available providers: `NewProviderMap`, `NewProviderStructTag` (`di-param` struct tags), `NewProviderComposite` (last provider holding a name wins), `NewProviderNull`. ## Generated File Conventions - Generated files are `*_gen.go` - Banner: `// Code generated by gendi; DO NOT EDIT.` ## Full documentation Each page below is HTML; [llms-full.txt](https://gendi.dev/llms-full.txt) is all of them concatenated as one Markdown file. - [Getting Started](https://gendi.dev/docs/): Install GenDI, declare a service, generate the container and use it — the whole loop once, with real generator output at every step. - [CLI](https://gendi.dev/docs/cli/): The generator's flags, the two built-in selectable passes, and the go:generate line that keeps a container in sync. - [Shipping Wiring in a Library](https://gendi.dev/docs/library-wiring/): Publishing a gendi.yaml from your own library so consumers import it by module path, without your API or dependency graph knowing about it. - [Compiler Passes](https://gendi.dev/docs/passes/): Writing a compiler pass that rewrites the configuration before generation, with worked examples and the rules that keep passes predictable. - [Troubleshooting](https://gendi.dev/docs/troubleshooting/): What each generation error means, keyed by the verbatim message, and what to change to make it go away. - [Building a Custom Generator](https://gendi.dev/docs/embedding/): Building your own generator binary around cmd.Run, so your passes run with the same flags, validation and diagnostics as the stock one. - [Design](https://gendi.dev/docs/design/): The four goals that shape GenDI, what the generated container guarantees, and what the project deliberately does not do. - [Notes for AI Agents](https://gendi.dev/docs/llm/): Everything an agent needs to write a GenDI configuration correctly, in short form — also served verbatim at /llms.txt. - [Configuration Reference](https://gendi.dev/docs/configuration/): The YAML surface of GenDI: schema validation, the four top-level keys, and a page per concept. - [Services](https://gendi.dev/docs/configuration/services/): Defining a service: the constructor, the optional type contract, and every field a service entry accepts. - [Constructors](https://gendi.dev/docs/configuration/constructors/): Declaring a constructor as a plain function, a method of another service, or a generic function with explicit type arguments. - [Parameters](https://gendi.dev/docs/configuration/parameters/): Scalar configuration values injected as %name%, their contextual target types, and the providers a container reads them through at run time. - [Arguments](https://gendi.dev/docs/configuration/arguments/): How a single argument is spelled: service and parameter references, tagged collections, the spread operator and the $this token. - [Service Lifecycle](https://gendi.dev/docs/configuration/lifecycle/): Shared and non-shared services, the single container mutex, and when the generator drops a cache that could not be observed anyway. - [Aliases and Visibility](https://gendi.dev/docs/configuration/visibility/): Aliases, public getters, and why a service you configured may not appear in the generated container at all. - [Decorators](https://gendi.dev/docs/configuration/decorators/): Wrapping a service with decorators, their priority order, and how @.inner and tags behave inside a chain. - [Tags](https://gendi.dev/docs/configuration/tags/): Collecting services by tag into a typed slice, sorting them by attribute, and autoconfiguring tags across a configuration. - [Service Defaults](https://gendi.dev/docs/configuration/defaults/): The reserved _default entry, which sets shared, public and autoconfigure for the services declared in the same file. - [Imports](https://gendi.dev/docs/configuration/imports/): Importing other configurations by relative path, glob or module path: resolution order, exclusions, merging and the sandbox around them. - [Complete Example](https://gendi.dev/docs/configuration/example/): A single configuration exercising imports, parameters, tags, decorators and stdlib services together.