Modules depinject-ready
depinject 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:
- Define the module configuration using Protobuf
- Define the module dependencies in
x/{moduleName}/module.go
A chain developer can then use the module by following these two steps:
- Configure the module in
app_config.goorapp.yaml - 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.
loading...
go_importmust 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.yamlfile for a chain developer to configure the module.
Takinggroupas example, a chain developer is able to decide, thanks touint64 max_metadata_len, what the maximum metadata length allowed for a group proposal is.simapp/app_config.goloading...
That message is generated using pulsar (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:
loading...
Pulsar is optional. The official protoc-gen-go 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.
All methods, structs and their fields must be public for depinject.
Import the module configuration generated package:
x/group/module/module.goloading...Define an
init()function for defining theprovidersof the module configuration:
This registers the module configuration message and the wiring of the module.x/group/module/module.goloading...Ensure that the module implements the
appmodule.AppModuleinterface:x/group/module/module.goloading...Define a struct that inherits
depinject.Inand define the module inputs (i.e. module dependencies):depinjectprovides the right dependencies to the module.depinjectalso checks that all dependencies are provided.tipFor making a dependency optional, add the
optional:"true"struct tag.x/group/module/module.goloading...
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.x/group/module/module.goloading...Create a function named
ProvideModule(as called in 1.) and use the inputs for instantiating the module outputs.x/group/module/module.goloading...
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:
loading...
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.