cosmos-sdk/docs/build/building-modules/15-depinject.md
2024-10-09 07:18:53 +00:00

131 lines
5.1 KiB
Markdown

---
sidebar_position: 1
---
# Modules depinject-ready
:::note Pre-requisite Readings
* [Depinject Documentation](../packages/01-depinject.md)
:::
[`depinject`](../packages/01-depinject.md) is used to wire any module in `app.go`.
All core modules are already configured to support dependency injection.
To work with `depinject` a module must define its configuration and requirements so that `depinject` can provide the right dependencies.
In brief, as a module developer, the following steps are required:
1. Define the module configuration using Protobuf
2. Define the module dependencies in `x/{moduleName}/module.go`
A chain developer can then use the module by following these two steps:
1. Configure the module in `app_config.go` or `app.yaml`
2. Inject the module in `app.go`
## Module Configuration
The module available configuration is defined in a Protobuf file, located at `{moduleName}/module/v1/module.proto`.
```protobuf reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/proto/cosmos/group/module/v1/module.proto
```
* `go_import` must point to the Go package of the custom module.
* Message fields define the module configuration.
That configuration can be set in the `app_config.go` / `app.yaml` file for a chain developer to configure the module.
Taking `group` as example, a chain developer is able to decide, thanks to `uint64 max_metadata_len`, what the maximum metadata length allowed for a group proposal is.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/simapp/app_config.go#L228-L234
```
That message is generated using [`pulsar`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/scripts/protocgen-pulsar.sh) (by running `make proto-gen`).
In the case of the `group` module, this file is generated here: https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/api/cosmos/group/module/v1/module.pulsar.go.
The part that is relevant for the module configuration is:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/api/cosmos/group/module/v1/module.pulsar.go#L515-L527
```
:::note
Pulsar is optional. The official [`protoc-gen-go`](https://protobuf.dev/reference/go/go-generated/) can be used as well.
:::
## Dependency Definition
Once the configuration proto is defined, the module's `module.go` must define what dependencies are required by the module.
The boilerplate is similar for all modules.
:::warning
All methods, structs and their fields must be public for `depinject`.
:::
1. Import the module configuration generated package:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L12-L14
```
Define an `init()` function for defining the `providers` of the module configuration:
This registers the module configuration message and the wiring of the module.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L194-L199
```
2. Ensure that the module implements the `appmodule.AppModule` interface:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.47.0/x/group/module/module.go#L58-L64
```
3. Define a struct that inherits `depinject.In` and define the module inputs (i.e. module dependencies):
* `depinject` provides the right dependencies to the module.
* `depinject` also checks that all dependencies are provided.
:::tip
For making a dependency optional, add the `optional:"true"` struct tag.
:::
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L201-L211
```
4. Define the module outputs with a public struct that inherits `depinject.Out`:
The module outputs are the dependencies that the module provides to other modules. It is usually the module itself and its keeper.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L213-L218
```
5. Create a function named `ProvideModule` (as called in 1.) and use the inputs for instantiating the module outputs.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L220-L235
```
The `ProvideModule` function should return an instance of `cosmossdk.io/core/appmodule.AppModule` which implements
one or more app module extension interfaces for initializing the module.
Following is the complete app wiring configuration for `group`:
```go reference
https://github.com/cosmos/cosmos-sdk/blob/v0.50.0-alpha.0/x/group/module/module.go#L194-L235
```
6. All modules must implement `depinject.OnePerModuleType` interface. This is used in order to tell the dependency injection framework that the module can only be instantiated once.
```go reference
https://github.com/cosmos/cosmos-sdk/blob/f4bdec3433373cc4950f4680743e969495763fbb/x/group/module/module.go#L64-L65
```
The module is now ready to be used with `depinject` by a chain developer.
## Integrate in an application
The App Wiring is done in `app_config.go` / `app.yaml` and `app_di.go` and is explained in detail in the [overview of `app_di.go`](https://docs.cosmos.network/main/build/building-apps/app-go-di).