107 lines
3.7 KiB
Go
107 lines
3.7 KiB
Go
package appconfig
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
|
|
"github.com/cosmos/gogoproto/proto"
|
|
|
|
internal "cosmossdk.io/depinject/internal/appconfig"
|
|
)
|
|
|
|
var Register = RegisterModule
|
|
|
|
// RegisterModule registers a module with the global module registry. The provided
|
|
// protobuf message is used only to uniquely identify the protobuf module config
|
|
// type. The instance of the protobuf message used in the actual configuration
|
|
// will be injected into the container and can be requested by a provider
|
|
// function. All module initialization should be handled by the provided options.
|
|
//
|
|
// Config is a protobuf message type. It should define the cosmos.app.v1alpha.module
|
|
// option and must explicitly specify go_packageto make debugging easier for users.
|
|
//
|
|
// If you want to customize an existing module, you need to overwrite by calling
|
|
// RegisterModule again with the same config (proto API type) and new Provide or
|
|
// Invoke options. Example:
|
|
//
|
|
// - Create a new struct and wrap the existing module inside it:
|
|
//
|
|
// type MyBankAppModule struct {
|
|
// bank.AppModule // core bank module
|
|
// // additional helper fields
|
|
// cdc codec.Codec
|
|
// }
|
|
//
|
|
// - Overwrite function that you want to customize (eg DefaultGenesis).
|
|
// - Create a new Provide function (to provide new Module implementation for the proto module):
|
|
//
|
|
// func ProvideBankModule(in bank.ModuleInputs) BankModuleOutputs {
|
|
// // original provider that initializes the bank keeper
|
|
// pm := bank.ProvideModule(in)
|
|
// m := NewMyBankAppModule(in.Cdc, pm.BankKeeper, in.AccountKeeper)
|
|
// return BankModuleOutputs{
|
|
// BankKeeper: pm.BankKeeper,
|
|
// Module: m,
|
|
// }
|
|
// }
|
|
//
|
|
// - Re-register the bank module by using the original proto api module, and the new provider:
|
|
//
|
|
// appconfig.RegisterModule(
|
|
// &bankmodulev1.Module{}, // from cosmossdk.io/api/cosmos/bank/module/v1
|
|
// appconfig.Provide(ProvideBankModule),
|
|
// appconfig.Invoke(bank.InvokeSetSendRestrictions),
|
|
// )
|
|
func RegisterModule(config any, options ...Option) {
|
|
protoConfig, ok := config.(proto.Message)
|
|
if !ok {
|
|
panic(fmt.Errorf("expected config to be a proto.Message, got %T", config))
|
|
}
|
|
|
|
ty := reflect.TypeOf(config)
|
|
init := &internal.ModuleInitializer{
|
|
ConfigProtoMessage: protoConfig,
|
|
ConfigGoType: ty,
|
|
}
|
|
internal.ModuleRegistry[ty] = init
|
|
|
|
for _, option := range options {
|
|
init.Error = option.apply(init)
|
|
if init.Error != nil {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// Option is a functional option for implementing modules.
|
|
type Option interface {
|
|
apply(*internal.ModuleInitializer) error
|
|
}
|
|
|
|
type funcOption func(initializer *internal.ModuleInitializer) error
|
|
|
|
func (f funcOption) apply(initializer *internal.ModuleInitializer) error {
|
|
return f(initializer)
|
|
}
|
|
|
|
// Provide registers providers with the dependency injection system that will be
|
|
// run within the module scope (depinject.ProvideInModule). See cosmossdk.io/depinject for
|
|
// documentation on the dependency injection system.
|
|
func Provide(providers ...interface{}) Option {
|
|
return funcOption(func(initializer *internal.ModuleInitializer) error {
|
|
initializer.Providers = append(initializer.Providers, providers...)
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// Invoke registers invokers to run with depinject (depinject.InvokeInModule). Each invoker will be called
|
|
// at the end of dependency graph configuration in the order in which it was defined. Invokers may not define output
|
|
// parameters, although they may return an error, and all of their input parameters will be marked as optional so that
|
|
// invokers impose no additional constraints on the dependency graph. Invoker functions should nil-check all inputs.
|
|
func Invoke(invokers ...interface{}) Option {
|
|
return funcOption(func(initializer *internal.ModuleInitializer) error {
|
|
initializer.Invokers = append(initializer.Invokers, invokers...)
|
|
return nil
|
|
})
|
|
}
|