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
- Configure the module in
app_config.go
orapp.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
.
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. Takinggroup
as 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.goSee full example on GitHub
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:
api/cosmos/group/module/v1/module.pulsar.go
Pulsar is optional. The official
protoc-gen-go
can be used as well.Dependency Definition
Once the configuration proto is defined, the module’smodule.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.go
See full example on GitHub Define an
init()
function for defining theproviders
of the module configuration: This registers the module configuration message and the wiring of the module. x/group/module/module.goSee full example on GitHub -
Ensure that the module implements the
appmodule.AppModule
interface: x/group/module/module.goSee full example on GitHub -
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.x/group/module/module.goFor making a dependency optional, add theoptional:"true"
struct tag.See full example on GitHub
-
-
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.goSee full example on GitHub -
Create a function named
ProvideModule
(as called in 1.) and use the inputs for instantiating the module outputs. x/group/module/module.goSee full example on GitHub
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
:
x/group/module/module.go
depinject
by a chain developer.
Integrate in an application
The App Wiring is done inapp_config.go
/ app.yaml
and app_v2.go
and is explained in detail in the overview of app_v2.go
.